YNAB MCP Server
This server gives an AI assistant a safe, read-only-by-default interface to YNAB budgeting data, with optional write tools, analytics, audits, and undo support.
View budgets & settings – list budgets, get summaries/delta exports, and check currency/date formats.
Manage accounts – list account balances, debt details, and import status; optionally create accounts.
Explore categories – list, search, and inspect categories, groups, goals, monthly budgets, and overspending.
Work with payees & locations – list, search, view, create, and rename payees; access GPS payee locations.
Review months & money movements – monthly summaries, per-category breakdowns, and budget re-allocation history.
Query transactions – filter by account/category/payee/month/status/date, search by text or amount, and export CSV.
Review unapproved transactions – group by readiness, flag anomalies, and use summary/compact modes.
Write to YNAB (when enabled) – create/update/delete transactions, batch approve, reassign payees, manage scheduled transactions, create accounts/categories/payees, import transactions, and merge/retire categories.
Run audits & analytics – credit card payment funding checks, reconciliation diagnosis, budget health, income/expense summaries, and recurring-charge detection.
Undo and audit writes – local undo journal listing and reversal of journaled operations.
Discover and orchestrate tools – auth status, tool index, and a generic executor for read-only tools.
Allows using 1Password CLI reference for token fallback to securely retrieve YNAB API token.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@YNAB MCP ServerHow much did I spend on groceries this month?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Run YNAB through Claude Code, Codex, Hermes, Antigravity, or any stdio MCP host. For clients that need a remote URL, the hosted connector at https://ynab.amesvt.com/mcp signs each user in through YNAB OAuth, with no personal access token to copy into another service. Both paths use the same rate-aware tool layer, speak in dollars instead of milliunits, start read-only, and journal writes so they can be undone.
Why This Exists
YNAB's budgeting philosophy works best when you interact with your budget frequently, but the app interface is not designed for quick questions or careful bulk cleanup. "How much did I spend on groceries this month?" should not require navigating three screens. "Categorize all my Amazon orders from this week" should not become a manual, one-by-one review.
This server gives your AI assistant a safe local interface to YNAB's API, turning natural language into structured budget review and, when explicitly enabled, budget operations. It is designed for real budgeting work: finding overspending, reviewing unapproved transactions, checking category drift, investigating recurring payments, and making verified batch updates without giving the assistant broader access than it needs.
All monetary values are automatically converted between dollars and YNAB's internal milliunits format so the AI never has to think about it. The server uses the official YNAB JavaScript SDK where it fits, plus direct API calls for newer endpoints and query parameters that the SDK has not caught up with yet.
Related MCP server: YNAB MCP Server
Quick Start
This package stands on its own as a stdio MCP server. You can register the npm package directly and let your MCP client launch it on demand. Plugin packages are also provided for separately managed Claude Code and Codex marketplaces, plus the included Hermes and Antigravity catalogs. You do not need the older ames-connectors marketplace for YNAB.
The npm package is the local, owner-run option. It uses a personal access token because the account owner runs the process. The same repository also powers a hosted OAuth connector for clients that accept remote MCP URLs.
Connect to the hosted remote server
Add this Streamable HTTP URL to Claude.ai, ChatGPT, Mistral Vibe Work, or another remote MCP client:
https://ynab.amesvt.com/mcpThe client opens this connector's consent page and then sends you to YNAB to sign in. Leave the write-access box unchecked for a read-only connection, or enable it when you need the write tools. The connector stores OAuth tokens and undo data with application-layer encryption in Cloudflare KV; the AI client receives only the connector's own scoped token. See the live privacy policy, data-deletion flow, and deployment documentation.
Signed-in acceptance passed on July 15, 2026, in ChatGPT, Claude.ai,
and Mistral Vibe Work. Each host completed OAuth, invoked the connector,
returned the live budget list, and reported writes_enabled: true for the
explicitly write-authorized grant. New grants still default to read-only, and
high-impact tools retain their own confirmed: true gate even when write tools
are visible.
Connector discovery advertises the 256px Blurple tree first and the square PNG
at https://ynab.amesvt.com/assets/icon.png second. The latter is generated
from the exact same codex/assets/icon.png artwork used by the Codex plugin.
The hosted consent,
callback, privacy, and deletion pages retain the permitted “Works with YNAB”
integration mark. The landing page also exposes the Blurple YNAB tree through
an SVG favicon, a conventional ICO, 16px, 32px, 48px, 64px, 96px, 128px, 256px,
and Apple touch icons for host favicon discovery. The page head advertises the
SVG first with the ICO as its alternate, because icon resolvers take the first
usable declaration; the remaining sizes stay served for other consumers. The
ICO carries a single 32px frame, since a six-frame uncompressed ICO reached
370 KB and resolvers skipped it rather than decode it. The 256px discovery
image uses standard 8-bit RGBA at the versioned
/assets/ynab-tree-icon-v1.png route. Host UIs can still cache an
older card image, so those presentation fields may need to be refreshed or
reindexed after the MCP metadata changes.
Install as a Plugin
Claude and Codex plugin packages remain available for distribution through a separately managed marketplace. This repository no longer supplies their root catalogs. For direct use, register the npm package with your MCP client.
The plugin starts @oliverames/mcp-server-for-ynab@latest and preserves the prior ames-ynab connector behavior by setting YNAB_ALLOW_WRITES=1. Direct MCP registration remains read-only unless you explicitly enable writes.
Other Plugin Hosts
The repository also carries host-specific marketplace and plugin manifests for Hermes and Antigravity:
Host | Marketplace | Plugin manifest | MCP config |
Claude Code | Separately managed |
|
|
Codex | Separately managed |
|
|
Hermes |
|
|
|
Antigravity |
|
|
|
1. Get a YNAB Personal Access Token
Go to YNAB Developer Settings and create a new personal access token.
Do not ask another YNAB user for a personal access token. If you are building a public connector for accounts you do not own, use YNAB OAuth instead.
Credential lookup order:
Values passed directly to the MCP process, such as
YNAB_API_TOKEN.The detected host's plaintext settings: Codex reads
~/.codex/config.toml, first[shell_environment_policy.set], then[mcp_servers.ynab.env]; Claude Code reads~/.claude/settings.jsonunder top-levelenv.The other supported agent config as a fallback, useful when a token is already stored locally but the launcher did not inject it.
YNAB_API_TOKEN_FILE, if configured in any of the sources above.YNAB_OP_PATH, if configured in any of the sources above and theopCLI is available.
If no token is found, ynab_auth_status returns a structured setup guide. Agents should first ask whether the user already has the YNAB token in a password manager such as 1Password. If yes, ask permission before configuring YNAB_OP_PATH; otherwise ask the user to add YNAB_API_TOKEN to the correct Codex or Claude config file and restart the MCP server.
2. Install in Claude Code
Use user scope if you want the server available in all Claude Code projects:
claude mcp add ynab --scope user \
-e YNAB_API_TOKEN=your-token-here \
-- npx -y @oliverames/mcp-server-for-ynab@latestAdd a default budget ID if you do not want tools to use YNAB's last-used budget:
claude mcp add ynab --scope user \
-e YNAB_API_TOKEN=your-token-here \
-e YNAB_BUDGET_ID=optional-default-budget-id \
-- npx -y @oliverames/mcp-server-for-ynab@latestUse --scope project instead of --scope user if you want Claude Code to write a project-local .mcp.json.
If ~/.claude/settings.json already contains env.YNAB_API_TOKEN, you may omit -e YNAB_API_TOKEN=...; the server will read the Claude setting as a fallback if the launcher does not inject it.
Verify Claude Code can see the server:
claude mcp get ynabIf Claude Code reports that ynab already exists, remove the old entry and run the add command again:
claude mcp remove ynab3. Install in Codex
Register the same npm package directly with Codex:
codex mcp add ynab \
--env YNAB_API_TOKEN=your-token-here \
-- npx -y @oliverames/mcp-server-for-ynab@latestWith a default budget ID:
codex mcp add ynab \
--env YNAB_API_TOKEN=your-token-here \
--env YNAB_BUDGET_ID=optional-default-budget-id \
-- npx -y @oliverames/mcp-server-for-ynab@latestIf ~/.codex/config.toml already contains YNAB_API_TOKEN under [shell_environment_policy.set] or [mcp_servers.ynab.env], you may omit --env YNAB_API_TOKEN=...; the server will read the Codex setting as a fallback if the launcher does not inject it.
Verify Codex can see the server:
codex mcp get ynabIf Codex reports that ynab already exists, remove the old entry and run the add command again:
codex mcp remove ynab4. Enable Write Tools (Optional)
By default, the server registers read-only tools only. To expose tools that create, update, import, or delete YNAB data, add YNAB_ALLOW_WRITES=1 when you register the server:
claude mcp add ynab --scope user \
-e YNAB_API_TOKEN=your-token-here \
-e YNAB_ALLOW_WRITES=1 \
-- npx -y @oliverames/mcp-server-for-ynab@latestcodex mcp add ynab \
--env YNAB_API_TOKEN=your-token-here \
--env YNAB_ALLOW_WRITES=1 \
-- npx -y @oliverames/mcp-server-for-ynab@latestDestructive direct tools, bulk-filter write tools such as approve_transactions and reassign_payee_transactions, and the generic ynab_write_tool_execute helper also require confirmed: true in the tool input after explicit user confirmation. For extra protection, pass expectedMatchedCount when using bulk-filter writes.
Manual JSON Config
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"ynab": {
"command": "npx",
"args": ["-y", "@oliverames/mcp-server-for-ynab"],
"env": {
"YNAB_API_TOKEN": "your-token-here"
}
}
}
}Generic MCP client:
{
"mcpServers": {
"ynab": {
"command": "npx",
"args": ["-y", "@oliverames/mcp-server-for-ynab"],
"env": {
"YNAB_API_TOKEN": "your-token-here"
}
}
}
}If you prefer a global install, point your MCP client at the package binary directly:
npm install -g @oliverames/mcp-server-for-ynab{
"mcpServers": {
"ynab": {
"command": "mcp-server-for-ynab",
"env": {
"YNAB_API_TOKEN": "your-token-here",
"YNAB_BUDGET_ID": "optional-default-budget-id"
}
}
}
}Docker (Optional)
The repository ships a Dockerfile (also used by registry-hosted builds such as Glama). The container speaks MCP over stdio:
docker build -t mcp-server-for-ynab .
docker run -i --rm -e YNAB_API_TOKEN=your-token-here mcp-server-for-ynabAdd -e YNAB_ALLOW_WRITES=1 to enable write tools, and -e YNAB_BUDGET_ID=... for a default budget.
1Password Token Lookup (Optional)
If your token is stored in 1Password, set YNAB_OP_PATH instead of YNAB_API_TOKEN. The op CLI must be installed and authenticated in the environment that launches the MCP server.
claude mcp add ynab --scope user \
-e YNAB_OP_PATH="op://Personal/YNAB API Token/credential" \
-- npx -y @oliverames/mcp-server-for-ynab@latestcodex mcp add ynab \
--env 'YNAB_OP_PATH=op://Personal/YNAB API Token/credential' \
-- npx -y @oliverames/mcp-server-for-ynab@latestLocal Smoke Test
From this repo, you can verify the published npm package without changing any MCP client config:
YNAB_API_TOKEN=your-token-here npm run smoke:review-unapproved -- --publishedWhat You Can Do
Ask your AI... | What happens under the hood |
"How much did I spend on groceries this month?" |
|
"Show me all unapproved transactions" |
|
"Log a $50 Costco trip under groceries" |
|
"Record my $250 Visa payment from checking" |
|
"Find the $12.34 charge from last week" |
|
"Set up monthly $1,500 rent on the 1st" |
|
"Move $200 from emergency fund to dining" |
|
"Categorize all my Amazon orders from this week" |
|
"Create a 'Side Projects' spending category" |
|
"How has my budget been re-allocated this month?" |
|
"What subscriptions am I actually paying for?" |
|
"How am I doing financially?" |
|
"Are my credit card payments fully funded?" |
|
"Merge my duplicate coffee categories" |
|
"Split that Costco charge across three categories" |
|
"Undo that last batch approval" |
|
"Import my latest bank transactions" |
|
Features
YNAB API v1.86 coverage with 59 tools when writes are enabled, plus MCP prompts and resources:
Resource | Tools | Capabilities |
Budgets | 4 | List, view details, settings |
Accounts | 3 | List, view, create |
Categories | 9 | Full CRUD, groups, search, goals, monthly budgets |
Payees | 5 | List, view, create, rename, search |
Payee Locations | 3 | GPS coordinates for mobile transactions |
Months | 2 | Monthly summaries with per-category breakdown |
Money Movements | 4 | Budget re-allocation tracking |
Transactions | 8 | Full CRUD, bulk ops, split transactions, multi-filter |
Scheduled Transactions | 5 | Full CRUD for recurring transactions |
Convenience | 2 | Unapproved transaction review and overspending checks |
Workflows | 3 | Category merge/retire, split-via-match for imported transactions |
Audits | 2 | Credit card payment funding, reconciliation diagnosis |
Analytics | 3 | Budget health, income/expense + savings rate, recurring-charge detection |
Undo & Export | 3 | Local undo journal for writes, CSV export |
Beyond tools, the server ships 6 MCP prompts (guided workflows: monthly review, weekly triage, categorize-and-approve, subscription audit, reconciliation, credit card audit) and 4 MCP resources (ynab://guide/*: YNAB methodology, write-safety rules, audit patterns, review flags reference).
Design Decisions
Read-only by default - write tools are not registered unless
YNAB_ALLOW_WRITES=1is set. Read tools are annotated withreadOnlyHint: true; write tools are annotated withreadOnlyHint: false, idempotency hints, and destructive hints for delete operations.Server instructions and structured contracts - the server sends a compact
instructionsblock at initialize (dollar amounts,search_transactionsbefore unfiltered pulls,transactionId, the transfer convenience, write-safety rules), so clients that never open a prompt or resource still get the rules that matter. Every tool exposes a human-readable title, an input schema even when it takes no arguments, a minimal output schema, and matchingstructuredContent. Impact hints describe YNAB as a private, bounded system so app clients can distinguish reads, writes, and destructive operations accurately.Explicit destructive confirmation - delete tools require
confirmed: truein their input after user confirmation. Bulk-filter writes also requireconfirmed: true, and supportexpectedMatchedCountwhen the current match count needs to be locked before mutation.Dollar amounts everywhere - inputs and outputs are in dollars (
-12.34), never milliunits (-12340). Conversion is automatic and transparent.Smart budget resolution - set
YNAB_BUDGET_IDfor a default, or omit it to auto-resolve to your last-used budget. Every tool accepts an optionalbudgetIdoverride.Pinned YNAB host - all HTTP requests are restricted to
https://api.ynab.com, redirects are not followed, and API tokens are redacted from surfaced errors.Agent-aware token fallback - use direct process env, Codex
~/.codex/config.toml, Claude~/.claude/settings.json, a small token file viaYNAB_API_TOKEN_FILE, or a 1Password CLI reference viaYNAB_OP_PATH.Split transactions - first-class support for subtransactions in create, read, and format operations. Updates can also convert a non-split transaction into a split (the YNAB API does not support editing the subtransactions of an existing split).
Current transaction filters - transaction list tools support
sinceDate,untilDate, type filters, resource filters, and delta requests. YNAB defaults omittedsinceDateto one year ago, so pass an explicit older date when you need older history.Bulk operations -
create_transactionsandupdate_transactionshandle arrays in a single API call. Bulk updates can look transactions up byidor byimportId.Verified batch updates -
update_transactionsrefetches the whole batch in a single list request after the bulk API call (instead of one request per transaction, which used to consume the shared rate budget on large batches), retries mismatched fields once through single-transaction updates, and returns averificationblock so approval counts cannot hide failed category writes.Fetch-then-merge updates - scheduled transaction updates (which use PUT semantics) automatically fetch the current state and merge your changes, so you only specify what changed.
Transfer convenience -
create_transactionandcreate_transactionsaccepttransferToAccountIdortransferToAccountNameand resolve the destination account'stransfer_payee_idthemselves, so a credit card payment is one call with no payee lookup. YNAB's own error for aTransfer : …payee name now carries the same pointer.Fuzzy search -
search_categoriesandsearch_payeesdo case-insensitive partial matching across all entries, andsearch_transactionsdoes the same over transactions (payee, raw import string, memo, account, category, split rows) with an optional absolute-amount match andlimit/offsetpaging. Category search covers both the category name and its group name, tokenizes multi-word queries and OR-matches them (sogym fitness membershipstill lands), ranks whole-phrase and name hits above single-token and group-only hits, and reportsmatched_on/matched_termsper result. It does no synonym expansion — an empty result says so and points atlist_categories.Decoded text - YNAB stores some strings HTML-escaped (bank imports are the usual source). Names, memos and notes are entity-decoded on the way out, so a payee reads as
B&H Photo Videorather thanB&H Photo Video, and name search matches either spelling. Writes send exactly what the caller supplied.Approval workflow with anomaly flags -
review_unapprovedscans the full transaction history for unapproved entries (YNAB's API defaults to the last year, which would silently hide older stragglers) and groups transactions into "ready to approve" (categorized, split, or transfer) and "needs attention" (uncategorized), and attaches aflagsarray to each transaction surfacing anomalies:manually_entered(not bank-imported),match_broken(stale match reference),scheduled_transaction_realized,new_payee,no_prior_amount_match(novel amount for this payee), andcategory_drift:was_X(payee categorized differently in the prior 60 days). Group-level flags aggregate the union of all transaction flags. Bulk approval requiresconfirmed: true.Honest group headers - a
by_payeegroup describes all of its rows, not just the first one. Groups carrycategory_names(every distinct category in the group) plusmixed_categories, andcategory_nameisnullwhenever the group spans more than one category.totalis the net; a group whose rows run both directions also carriesmixed_amount_signs: truewithinflow_totalandoutflow_total, so a net that nets refunds against charges cannot be read as a single small charge.Nullable updates - update tools accept
nullfor clearable fields (memo,payeeName,categoryId,flagColor) to distinguish "don't change" (omit) from "clear this field" (null).Target behavior support - category create/update tools expose
goalNeedsWholeAmountfor YNAB's "Set aside another" vs. "Refill up to" goal behavior.Delta request support - high-volume list tools accept
lastKnowledgeOfServerand returnserver_knowledgewhen that parameter is provided.get_budgetsupports full delta exports: passlastKnowledgeOfServerto receive every entity changed since that knowledge in one response.Undo journal - every transaction write is journaled locally with before-state (
~/.ynab-mcp-undo.json);list_undo_historyreviews it andundo_operationreverses a journaled write. Category/payee/scheduled writes are journaled for audit without automatic undo.Prompts and resources - guided workflow prompts (monthly review, weekly triage, categorize-and-approve, subscription audit, reconciliation, credit card audit) and a general YNAB-methodology knowledge base as MCP resources, so any host gets the working discipline without a separate skill.
Rate-budget surfacing - responses warn the model when 50 or fewer requests remain in the trailing hour, on top of the client-side limiter that enforces the budget.
Debt account support - loan and debt accounts include
debt_original_balance,debt_interest_rates,debt_minimum_payments, anddebt_escrow_amountswith correct unit conversion (rates stay as percentages, payments convert from milliunits).
Tools Reference
Read tools are available by default. Tools that create, update, import, or delete YNAB data are marked as write tools and are registered only when YNAB_ALLOW_WRITES=1.
User & Budgets
Tool | Description |
| Get the authenticated user |
| List all budgets with IDs, names, date ranges, format settings, and default budget. Pass |
| Get budget summary (name, currency, account/category/payee counts). Pass |
| Get currency and date format settings |
Accounts
Tool | Description |
| List all accounts with balances, debt details, and import status |
| Get full account details including notes and debt fields |
| Write tool: create a new account (checking, savings, creditCard, mortgage, etc.) |
Supported account types: checking, savings, cash, creditCard, lineOfCredit, otherAsset, otherLiability, mortgage, autoLoan, studentLoan, personalLoan, medicalDebt, otherDebt
Categories & Category Groups
Tool | Description |
| List all category groups and their categories with budgeted/activity/balance. Groups and categories carry |
| Get full category details including goal progress and cadence |
| Get category budget for a specific month |
| Write tool: set the budgeted amount for a category in a month |
| Write tool: update name, note, goal target, goal target date, or move to a different group. |
| Write tool: create a new category in an existing group, with an optional goal including a recurring |
| Write tool: create a new category group |
| Write tool: rename a category group |
| Case-insensitive partial name search over category names and category-group names (e.g., "groc" finds "Groceries"; "health" finds everything in a "Health & Medical" group). Multi-word queries are tokenized and OR-matched, results are ranked, and each result reports |
Payees
Tool | Description |
| List all payees with transfer account mappings |
| Get payee details |
| Write tool: create a new payee |
| Write tool: rename a payee |
| Case-insensitive partial name search |
Payee Locations
Tool | Description |
| List all payee locations (GPS coordinates from mobile app) |
| Get a specific payee location |
| Get all locations for a specific payee |
Months
Tool | Description |
| List budget months with income, budgeted, activity, to-be-budgeted, age of money, and notes |
| Get month detail with per-category budget/activity/balance/goal breakdown |
Money Movements
Tool | Description |
| List all money movements (budget re-allocations between categories) |
| Get money movements for a specific month |
| List all money movement groups (batched re-allocations) |
| Get money movement groups for a specific month |
Transactions
Tool | Description |
| Get transactions with filters: by account, category, payee, month, status ( |
| Server-side search with pagination: |
| Get a single transaction by ID. The argument is |
| Write tool: create a transaction with optional split (subtransactions must sum to total). For a transfer (including a credit card payment) pass |
| Write tool: bulk create multiple transactions in a single API call (supports split transactions and the same |
| Write tool: partial update - only specified fields change. Can convert a non-split transaction into a split via |
| Write tool: batch update multiple transactions at once (look up each entry by |
| Write tool: approve unapproved transactions in bulk by filter ( |
| Write tool: move all transactions from one payee to another, the merge workaround since the YNAB API has no payee delete/merge endpoint. Requires |
| Write tool: delete a transaction. Requires |
| Write tool: trigger import from linked bank accounts |
Scheduled Transactions
Tool | Description |
| List all recurring transactions |
| Get a specific scheduled transaction |
| Write tool: create a recurring transaction with frequency |
| Write tool: update (fetch-then-merge preserves unchanged fields) |
| Write tool: delete a scheduled transaction. Requires |
Supported frequencies: never, daily, weekly, everyOtherWeek, twiceAMonth, every4Weeks, monthly, everyOtherMonth, every3Months, every4Months, twiceAYear, yearly, everyOtherYear
Convenience
Tool | Description |
| Get unapproved transactions grouped by readiness: "ready to approve" (categorized, split, or transfer) vs. "needs category first" (uncategorized). Each transaction includes a |
| Get categories with negative balances for a month, useful for finding prior-month overspending that reduces the current month's Ready to Assign. |
Workflows (v4.0)
The YNAB API has no category merge/delete endpoint and cannot split an already-imported transaction; these composite tools do everything the API allows and report the remaining manual UI step.
Tool | Description |
| Recategorize every transaction from one category into another and move budgeted amounts ( |
| Prepare a category for deletion: move its transaction history to a replacement category and zero its budgets (dollars return to Ready to Assign). Requires |
| Create a mirror unapproved split transaction that YNAB will offer to match with an imported original, the only way to get splits onto a bank-imported transaction. Requires |
Audits & Analytics (v4.0, read-only)
Tool | Description |
| Compare each credit card's balance against its Credit Card Payment category and report underfunded cards. |
| Per-account reconciliation status; with |
| Snapshot with green/yellow/red indicators: savings rate, age of money, Ready to Assign, overspending, credit card debt. |
| Income vs. spending by month with savings rate, transfers excluded. |
| Find subscriptions/recurring charges from history by payee + amount + cadence, with estimated annual cost. |
| Export filtered transactions as CSV text. Capped at |
Undo Journal (v4.0)
Every transaction write (create, update, bulk update, approve, reassign, delete, and the category workflows) is journaled to a local file (~/.ynab-mcp-undo.json, last 100 entries) with before-state.
Tool | Description |
| List journaled writes, newest first, with undo capability per entry. Reads only the local journal. |
| Reverse a journaled write: restore updated fields, delete created transactions, or recreate a deleted one (without its original bank-import linkage). One undo per entry. Requires |
Workflow Safety Notes
Write Tool Opt-In
The server starts in read-only mode. Write tools are not merely discouraged; they are absent from listTools unless YNAB_ALLOW_WRITES=1 is present when the MCP process starts. This mirrors the safer hosted-connector pattern: the default permission set can inspect budgets, transactions, categories, payees, months, and scheduled transactions, but it cannot mutate financial data.
If a client already has the process running, changing the environment is not enough. Restart the MCP server after setting or clearing YNAB_ALLOW_WRITES.
High-impact writes require confirmation in the tool input, not only in surrounding chat. This applies to direct delete tools, approve_transactions, reassign_payee_transactions, and ynab_write_tool_execute:
{
"confirmed": true,
"expectedMatchedCount": 3,
"payeeId": "payee-id-to-approve"
}If expectedMatchedCount is provided and the current match count differs, the tool returns an error before mutating any transactions.
Batch Updates
When a batch operation categorizes and approves transactions at the same time, do not use review_unapproved counts as the only success check. Approved transactions leave the review queue even if a category write failed, so queue counts can hide approved-but-still-uncategorized transactions.
update_transactions protects this path by refetching the batch after the bulk API call (one list request for the whole batch, not one request per transaction) and comparing the persisted fields with the requested fields. If anything differs, it retries that transaction once through a single-transaction update. The response includes:
{
"verification": {
"checked": 1,
"retried": [],
"failed": []
}
}Treat any failed entry as a real write failure and inspect the named transaction with get_transaction.
Approval counts
Batch responses report two different approval numbers, and only one of them answers "what did this call approve?":
{
"updated_count": 9,
"approved_count": 3,
"newly_approved_count": 1,
"already_approved_count": 2,
"approval_state_unknown_count": 0
}approved_count is how many rows in the batch are approved now, including rows that were already approved when the batch was submitted. newly_approved_count is how many rows this call actually flipped, measured against the pre-write fetch; already_approved_count and approval_state_unknown_count (no before-state available, e.g. an importId row whose refetch failed) account for the rest. Report newly_approved_count to a user. approve_transactions only ever touches rows that were unapproved when it fetched them, so there the two are equal.
Composite Scheduled-Transaction IDs
A scheduled transaction that has realized carries a composite ID of the form d9e7c3c2-…_2026-07-30 (the shape review_unapproved flags as scheduled_transaction_realized). The suffix makes the ID look synthetic, and the natural assumption is that such a row is read-only or that the suffix must be stripped before writing. Neither is true: pass the ID exactly as returned and update_transaction / update_transactions apply memo, category and approval to the realized transaction, returning the full updated object. Reads are equally forgiving — get_transaction strips the suffix itself and falls back to the scheduled template when the underlying matched transaction has been deleted.
Credit Card Payment Transfers
If two unapproved transactions are clearly a credit card payment plus the matching checking-account outflow, convert them into a transfer before approval. Approving both sides as ordinary categorized transactions preserves the wrong structure and creates cleanup work.
Manual YNAB transfer fixes can replace one side of the pair with a new transaction ID. Read-only verification should not assume both original IDs survive. If one old ID returns resource_not_found, inspect recent activity in both involved accounts and verify the pair by transfer_transaction_id cross-links.
Environment Variables
Variable | Required | Default | Description |
| Yes* | (none) | Personal access token from YNAB Developer Settings. Read from process env first, then supported Codex and Claude plaintext agent settings. |
| No | (none) | Path to a file containing only the token. The file must be 4 KB or smaller. Used only when |
| No |
| Default budget ID. If omitted, tools use YNAB's most recently accessed budget. Run |
| No | read-only | Set to |
| No | (none) | 1Password secret reference for your API token. Used only if no direct token is configured. Can be provided through process env or agent settings. |
| No |
| Set to |
| No |
| Client-side rate limiter. Set to |
| No |
| Maximum burst size before rate limiting pauses requests. |
| No |
| Per-request timeout in milliseconds. Set to |
| No |
| Automatic retries for retryable failures. HTTP 429 (rate limited) retries any request because YNAB rejected it before processing; 502/503/504 and network errors retry reads ( |
| No |
| Maximum direct-fetch response size for newer endpoints. |
*YNAB_API_TOKEN is required unless YNAB_API_TOKEN_FILE or YNAB_OP_PATH is set. These values may come from direct process env, Codex config, or Claude settings.
Configuration Validation
Numeric environment variables are parsed at startup. A value that is not a number,
or that falls below the minimum for its setting, is ignored: the server keeps the
documented default and writes a warning to stderr naming the variable, the offending
value, and the fallback it used. This covers YNAB_RATE_LIMIT_PER_HOUR,
YNAB_RATE_LIMIT_BURST, YNAB_HTTP_TIMEOUT_MS, YNAB_HTTP_RETRIES, and
YNAB_MAX_RESPONSE_BYTES.
Zero is a valid, documented setting for YNAB_RATE_LIMIT_PER_HOUR,
YNAB_HTTP_TIMEOUT_MS, and YNAB_HTTP_RETRIES, so it is accepted rather than
replaced.
Input Validation
Write tools reject over-long text before the request reaches YNAB, using the limits in YNAB's own API specification:
Payee names on transactions (
payeeName): 200 charactersPayee names on
create_payeeandupdate_payee: 500 charactersCategory group names: 50 characters
Memos: 500 characters
The two payee limits differ because YNAB's API sets them differently. The
transaction endpoints cap payee_name at 200, while the payee endpoints cap the
payee resource name at 500.
1Password Integration
If you store your YNAB token in 1Password CLI, set YNAB_OP_PATH to your secret reference and omit YNAB_API_TOKEN:
{
"mcpServers": {
"ynab": {
"command": "npx",
"args": ["-y", "@oliverames/mcp-server-for-ynab"],
"env": {
"YNAB_OP_PATH": "op://Personal/YNAB API Token/credential"
}
}
}
}The fallback adds ~1-2s to startup. If op is unavailable or the item is not found, ynab_auth_status reports the lookup problem and returns setup guidance instead of letting a normal YNAB tool fail with a generic unauthorized error. If no token source is configured, the setup guide tells the calling agent to ask whether you have a token in 1Password or another password manager, request permission before editing agent config, and otherwise ask you to add YNAB_API_TOKEN to the appropriate Codex or Claude settings file.
Amount Handling
All amounts in tool inputs and outputs are in dollars (e.g., -12.34 for a $12.34 outflow). The server converts to/from YNAB's internal milliunits format automatically.
Direction | Sign | Example |
Outflow (spending) | Negative |
|
Inflow (income) | Positive |
|
Transfer out | Negative |
|
Transfer in | Positive |
|
Rate Limiting
The YNAB API allows 200 requests per hour per access token, enforced on a rolling window. This server applies a client-side limiter at 190 requests per hour with a burst of 10 by default. Each tool call typically uses one API request, except tools that deliberately verify or merge writes (update_transactions, approve_transactions, reassign_payee_transactions, update_scheduled_transaction) which perform a small, constant number of additional reads. Batch verification uses one list request for the whole batch regardless of batch size.
If a request still hits YNAB's limit (HTTP 429), the server waits for the Retry-After interval and retries automatically (up to YNAB_HTTP_RETRIES times). Transient 502/503/504 responses and network failures are retried for read requests only, since a failed write may have partially applied on the server.
Set YNAB_RATE_LIMIT_PER_HOUR=0 only for controlled local tests or smoke checks where you know you will stay under YNAB's API limit.
When the trailing-hour budget drops to 50 requests or fewer, tool responses append a pacing warning so the calling model can switch to delta requests, summary modes, and batch tools before hitting the wall.
Architecture
┌─────────────────────┐ ┌──────────────────┐ ┌──────────────┐
│ AI Assistant │────▶│ MCP Server for │────▶│ YNAB API │
│ │ │ YNAB │ │ │
│ (Claude, GPT, etc) │◀────│ (this package) │◀────│ api.ynab.com│
└─────────────────────┘ └──────────────────┘ └──────────────┘
MCP stdio transport HTTPS/RESTTransport: stdio (standard MCP server pattern)
Auth: Bearer token via process env, Codex or Claude agent config,
YNAB_API_TOKEN_FILE, orYNAB_OP_PATHfor local owner-run useSDK: Official
ynabv4.1+ for core endpoints, directfetchfor newer API features and v1.85 transaction filtersSafety: read-only default, explicit write opt-in, confirmation gates for destructive and bulk-filter writes, host-pinned HTTPS requests to
api.ynab.com, no redirect following, redacted token errorsValidation: All parameters validated with Zod schemas
Error handling: API errors are caught, formatted, and returned as MCP error responses with detail messages
The hosted OAuth connector runs on Cloudflare Workers at ynab.amesvt.com. Its implementation notes are in worker/README.md and docs/hosted-oauth-connector.md. For data handling details for the local package, see docs/privacy.md.
The Cloudflare connector is separate from the private Glama deployment below. YNAB initially places OAuth applications in Restricted Mode: the owner is exempt, while the app may obtain at most 25 access tokens for other users before new authorizations are blocked. YNAB says removal review takes 2 to 4 weeks. No review or public directory submission is part of the current deployment.
Glama Hosting
The repo is ready for Glama MCP hosting: the root glama.json claims the registry listing (per Glama's glama.json spec), and the Dockerfile is what Glama's GitHub integration builds. To deploy: Glama dashboard → MCP Hosting → deploy from GitHub → select this repo, then set environment variables YNAB_API_TOKEN (required), YNAB_BUDGET_ID (recommended), and YNAB_DISABLE_AGENT_CONFIG_FALLBACK=1 (no agent config files exist in the container). Leave YNAB_ALLOW_WRITES unset until you have verified the deployment read-only, and keep the deployment private because its env vars hold your personal token. YNAB_OP_PATH is unsupported in hosted containers (no 1Password CLI); the server reports this explicitly and falls back to discovery-only mode rather than crashing. Glama wraps the stdio transport as a Streamable HTTP Gateway endpoint automatically.
Public Listing Readiness
This repository is production-ready as a local owner-run stdio MCP package. The hosted OAuth connector is live under the YNAB application's initial Restricted Mode and has completed private signed-in acceptance in ChatGPT, Claude.ai, and Mistral Vibe Work. Public review and directory publication remain separate decisions:
If YNAB accepts a local owner-run package, submit this package with the published privacy policy, non-affiliation language, read-only default, write opt-in, confirmation gates, and test evidence.
The hosted connector uses the YNAB authorization-code flow with PKCE, a public privacy policy, and a user-facing deletion flow.
Keep public display names in the "for YNAB" pattern and avoid names that imply sponsorship or official support.
Testing
Offline Tests (no YNAB account required)
Unit tests cover the pure helpers (amount conversion, ID normalization, update verification, config parsing, URL safety, executor input validation), and the safety-model tests boot the real server over stdio to verify the read-only default, write-tool gating, annotations, and credential fallback behavior:
npm run test:unit
npm run test:safety
cd worker && npm testThe root suites run in CI (.github/workflows/ci.yml) on Node 20, 22, and 24 for every push and pull request, along with release:check and a credential-free MCP smoke test. The Worker suite covers consent-page escaping, OAuth state and PKCE, encrypted KV records, token refresh races, and paginated grant deletion.
Live Integration Tests
The integration test suite runs against a live YNAB budget. Most write tests create temporary transactions and delete or restore them, but category and category group creation is not reversible through the public API and is skipped unless explicitly enabled.
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id npm testUse YNAB_TEST_BUDGET_ID to target a dedicated test budget without changing your server default. To include category and category group creation coverage, run with YNAB_RUN_NONREVERSIBLE_TESTS=1.
Tests cover all tool categories: reads, reversible writes, bulk operations, search, split transactions, scheduled transaction CRUD with fetch-then-merge verification, money movements, and payee locations.
MCP Smoke Tests
Use the smoke tests when you need to prove the server is reachable over stdio without reconstructing a custom MCP client. These commands use the official MCP SDK client, the same transport shape used by normal MCP hosts. smoke:list-tools can run without a live token to verify discovery, but live read and write smokes need a token from process env, supported Codex or Claude settings, YNAB_API_TOKEN_FILE, or YNAB_OP_PATH.
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id npm run smoke:list-tools
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id npm run smoke:review-unapproved
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id YNAB_ALLOW_WRITES=1 npm run smoke:batch-verifyTo test the package currently published to npm instead of the local checkout:
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id npm run smoke:list-tools -- --published
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id npm run smoke:review-unapproved -- --published
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id YNAB_ALLOW_WRITES=1 npm run smoke:batch-verify -- --publishedsmoke:list-tools verifies that high-value read tools such as review_unapproved, get_transactions, search_transactions, search_categories, and search_payees are present. When YNAB_ALLOW_WRITES=1 is set, it also verifies update_transactions. smoke:review-unapproved calls review_unapproved with summary: true and prints only aggregate counts. smoke:batch-verify creates a temporary transaction, uses update_transactions to categorize and approve it in one call, refetches it through the MCP server, and deletes it afterward.
Development
See CONTRIBUTING.md for the local checks and pull request guidelines. Report suspected vulnerabilities through the private process in SECURITY.md.
git clone https://github.com/oliverames/ynab-mcp-server.git
cd ynab-mcp-server
npm install
YNAB_API_TOKEN=your-token npm startDependencies
@modelcontextprotocol/sdk- MCP server frameworkynab- Official YNAB JavaScript client
Zero additional dependencies. No build step. Pure ESM.
Release Checks
Before publishing, run:
npm run sync:plugin
npm run release:check
npm pack --dry-runAfter publishing, run npm run release:check:registry to verify the npm latest dist-tag and repo metadata agree on the same version. npm run build:mcpb remains available for an explicit local bundle, but the normal install path is direct MCP registration through npm.
Pushing a v* tag triggers the release workflow (.github/workflows/release.yml), which verifies the tag against package.json, re-runs the offline tests and consistency checks, builds the MCPB bundle, and publishes a GitHub release with the bundle attached.
Privacy and Non-Affiliation
See docs/privacy.md for this connector's data handling, deletion, and token-use details.
This connector is not affiliated, associated, or in any way officially connected with YNAB or any of its subsidiaries or affiliates. The official YNAB website can be found at https://www.ynab.com.
The names YNAB and You Need A Budget, as well as related names, trade names, marks, trademarks, emblems, and images are registered trademarks of YNAB.
License
MIT
Available Tools
39 toolsaudit_account_reconciliationAudit Account ReconciliationARead-onlyIdempotent
Read-only reconciliation diagnosis. Without accountId: summarizes every open account's last-reconciled date and cleared/uncleared balances (one API request). With accountId: additionally lists that account's uncleared and unapproved transactions since the last reconciliation, which are exactly the rows to compare against the bank statement. Makes no changes — actual reconciliation (marking transactions reconciled and locking the balance) happens in the YNAB UI; use this to find what needs attention first. Interpretation note: an old last_reconciled_at is not itself a problem if cleared_balance matches the bank; uncleared transactions older than a few days are the usual culprits.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| accountId | No | Account to inspect in detail (adds that account's uncleared/unapproved transaction list) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, but the description adds specifics: it performs a single API request without accountId, lists uncleared/unapproved transactions with accountId, and helps compare against the bank statement. This is valuable behavioral context beyond the annotations, and it reinforces the read-only promise by stating 'Makes no changes.' No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and the parameter-dependent behavior, and each subsequent sentence earns its place by covering usage and interpretation. Despite its length, there is no redundancy or filler; the structure mirrors the decision process an agent would follow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the return format is covered. The description fully explains what the tool does, when to use it, how to interpret results, and what it does not do (actual reconciliation). Nothing an agent needs to call this correctly and interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for both parameters, but the description adds crucial semantics: it explains how the presence or absence of accountId changes the tool's behavior (summary vs. detail listing). This goes far beyond the schema's bare field descriptions and directly informs the agent which parameter to set for the desired outcome.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource ('Read-only reconciliation diagnosis') and then distinguishes two modes (with/without accountId) that map cleanly to the two parameters. It clearly separates this tool from siblings like audit_credit_card_payments by focusing on reconciliation state rather than card payment issues.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it ('use this to find what needs attention first') and when not to (actual reconciliation happens in the YNAB UI). It also provides an interpretation note that helps the agent decide if a finding is actionable, which is exactly the kind of usage guidance that reduces mis-calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audit_credit_card_paymentsAudit Credit Card PaymentsARead-onlyIdempotent
Read-only audit of credit card payment categories: for each open credit card / line of credit account, compares the card's balance with its Credit Card Payment category's available balance. In a healthy budget the payment category equals the card balance (sign-flipped) for spending that is budgeted; a shortfall means a future payment is not fully funded (common after overspending or direct debt increases). Reports each card's balance, payment-category balance, difference, and a status. Makes no changes — fix shortfalls by assigning to the payment category via update_month_category. Interpretation note: small transient differences appear while recent transactions are pending/uncleared; treat sub-dollar or same-day differences as timing, not error.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already mark the tool read-only, idempotent, and non-destructive, the description adds valuable behavior: it 'makes no changes,' reports each card's balance/category balance/difference/status, and warns that pending/uncleared transactions can cause transient sub-dollar differences to be treated as timing rather than error. This goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core audit purpose and flows naturally into purpose, healthy/unhealthy interpretation, output contents, non-mutating behavior, and a practical caveat. Every sentence adds information; there is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only audit tool with an output schema and a single optional parameter, the description fully covers what the tool computes, what the results mean, what it does not do, and how to interpret edge cases. Nothing material is missing for an agent to invoke it confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, budgetId, is fully described in the schema ('Budget ID (uses default if not provided)'), so schema coverage is 100%. The description adds no budgetId-specific semantics, but none are needed because the schema already handles it; this is the appropriate baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Read-only audit of credit card payment categories' and precisely defines the behavior: comparing each open card/line-of-credit balance with the corresponding payment category's available balance. This clearly distinguishes it from generic read tools like get_account or get_category, and from the fix-oriented update_month_category tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when this audit is relevant (healthy budgets show a sign-flipped match; shortfalls indicate underfunded future payments) and gives an actionable alternative: 'fix shortfalls by assigning to the payment category via update_month_category.' This is strong when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_recurring_chargesDetect Recurring ChargesARead-onlyIdempotent
Read-only detection of recurring charges (subscriptions, utilities, insurance) from transaction history: groups outflows by payee + exact amount and reports groups whose spacing matches a weekly/biweekly/monthly/quarterly/yearly cadence, with estimated annual cost. Use for subscription audits and 'what am I paying for' questions. Catches auto-imported recurring charges that list_scheduled_transactions cannot see (that tool only lists manually-created recurrences). Limitations: variable-amount bills (utilities that fluctuate) are missed because grouping is by exact amount; the same vendor billed under multiple identities or payee spellings appears as separate rows — verify against payee variants with search_payees before concluding a subscription was cancelled.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| monthsBack | No | History window in months (default 6; longer windows catch quarterly/yearly cadences) | |
| minOccurrences | No | Minimum occurrences to count as recurring (default 3) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral context: exact-amount grouping, cadence matching, estimated annual cost, and important limitations that affect interpretation. This goes well beyond what the annotations alone convey and does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed yet well-structured: the core function and use case come first, followed by the key sibling distinction and then limitations. Every sentence carries essential information, and the length is justified by the tool's analytical complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations, complete parameter schema, and presence of an output schema, the description covers everything an agent needs to select and invoke the tool correctly. It explains what the tool catches, what it misses, and how to verify ambiguous results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully describes all three parameters, including defaults and the effect of monthsBack on cadence detection. The description reinforces the grouping-by-exact-amount limitation that explains why minOccurrences matters, but it does not add substantial parameter-level detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: read-only detection of recurring charges from transaction history, with specific methodology (grouping by payee + exact amount and cadence detection). It also distinguishes itself from list_scheduled_transactions, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided for when to use this tool ('subscription audits' and 'what am I paying for' questions), and when not to rely on it (variable-amount bills, payee spelling variants). It also names the alternative tool and the verification step with search_payees, giving clear decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_transactionsExport TransactionsARead-onlyIdempotent
Export transactions as CSV text (same filters as get_transactions, including type). Columns: date, amount (dollars, negative = outflow), payee, category, account, memo, cleared, approved, transfer, id. Free-text columns (payee, category, account, memo) get a leading apostrophe when the value starts with a formula character (= + - @ tab CR), so spreadsheet applications cannot execute a bank-imported merchant string as a formula. Use when the user wants data for a spreadsheet or offline analysis; for programmatic work prefer get_transactions (structured JSON). Read-only. Large date ranges produce large output — narrow with filters when possible.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by approval/categorization status (e.g. export the unapproved queue for offline review) | |
| month | No | Filter by month (YYYY-MM-DD, first of month) | |
| maxRows | No | Row cap (default 500, max 2000). When exceeded, the newest rows are kept and a second text block reports the truncation. | |
| payeeId | No | Filter by payee ID | |
| budgetId | No | Budget ID (uses default if not provided) | |
| accountId | No | Filter by account ID | |
| sinceDate | No | Only export transactions on or after this date (YYYY-MM-DD). If omitted, YNAB defaults to one year ago. | |
| untilDate | No | Only export transactions on or before this date (YYYY-MM-DD) | |
| categoryId | No | Filter by category ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (read-only, idempotent, non-destructive), the description discloses several important behaviors: CSV column semantics ('negative = outflow'), formula-injection protection via leading apostrophe and why it exists, and a warning about large date ranges producing large output. The 'Read-only' line is redundant with annotations but does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficiently structured, front-loading the core purpose and then adding column details, security rationale, usage guidance, and a size warning. The only mild redundancy is the standalone 'Read-only.' sentence, which duplicates the readOnlyHint annotation, so it does not receive a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 optional parameters, an output schema, and a non-trivial CSV formatting behavior, the description covers everything an agent needs to select and invoke it correctly: format, columns, amount sign convention, formula-injection safety, usage context, and scale warning. Nothing important is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema carries the parameter documentation burden. The description adds a useful hint that filters are shared with get_transactions and highlights the 'type' filter, but it does not materially elaborate on individual parameters. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Export transactions as CSV text.' It also names the format and explicitly contrasts with get_transactions ('same filters as get_transactions'), making the tool's role unambiguous relative to its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance is provided: 'Use when the user wants data for a spreadsheet or offline analysis; for programmatic work prefer get_transactions (structured JSON).' It also advises narrowing filters for large ranges, giving the agent actionable selection and invocation rules.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_accountGet AccountARead-onlyIdempotent
Get one account's details: balances (dollars), type, reconciliation timestamp, and debt metadata. Read-only. Prefer list_accounts when comparing several accounts; use this when you already have the account ID and want fresh detail.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| accountId | Yes | Account ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds 'Read-only' (redundant) and 'fresh detail' (implies live fetch). Minimal additional behavioral context beyond annotations, but no contradiction. Baseline 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose and details, then usage guidance. Every sentence earns its place with zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-account fetch with an output schema and annotations covering safety, the description is complete: it states what it returns, when to use it, and that it's read-only. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents accountId and budgetId. The description does not add parameter-specific semantics beyond what the schema provides; it lists output fields but not parameter usage. Baseline 3 stands.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and resource ('one account's details') and enumerates the specific data returned (balances, type, reconciliation timestamp, debt metadata). Explicitly distinguishes itself from list_accounts by stating it is for single-account detail retrieval when the ID is already known.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear, explicit guidance on when to use this tool versus the sibling list_accounts: 'Prefer list_accounts when comparing several accounts; use this when you already have the account ID and want fresh detail.' No ambiguity left for the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_budgetGet BudgetARead-onlyIdempotent
Get a budget summary including name, currency format, and account/category/payee counts. Pass lastKnowledgeOfServer to get a delta export instead: every entity (accounts, payees, categories, months, transactions, scheduled transactions, ...) that changed since that server knowledge, plus the new server_knowledge for the next delta request. A delta request with lastKnowledgeOfServer: 0 returns the full budget export, which can be very large — responses over the YNAB_MAX_RESPONSE_BYTES cap (default 8 MB) are rejected; on big budgets prefer incremental deltas or the dedicated list tools.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns changed entities and server_knowledge instead of the summary. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and idempotent, and the description adds substantial behavioral context: the delta response includes changed entities plus new server_knowledge, responses over YNAB_MAX_RESPONSE_BYTES are rejected, and the default cap is 8 MB. This goes well beyond the annotation hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the primary purpose, followed by the delta mode and a practical size-limit warning. Every sentence earns its place and the structure is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, return values need no explanation. The description covers both usage modes, the special lastKnowledgeOfServer: 0 behavior, the size cap, and alternatives for large budgets. An agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful parameter behavior beyond the schema by explaining that lastKnowledgeOfServer: 0 returns the full budget export and that large responses may be rejected, plus guidance to prefer incremental deltas. This is extra semantic value, though some delta semantics are already present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Get a budget summary') and enumerates the exact contents (name, currency format, counts). It also describes the delta-export alternative, which clearly distinguishes this tool from siblings like get_budget_settings and list_budgets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to use the delta mode versus the summary mode, warns that lastKnowledgeOfServer: 0 returns a very large full export, and directs users to prefer incremental deltas or dedicated list tools on big budgets. This is explicit when/when-not guidance with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_budget_healthGet Budget HealthARead-onlyIdempotent
Read-only budget health snapshot combining month data, account balances, and a trailing-3-month income/spending summary: savings rate, age of money, Ready to Assign, overspent categories, credit card payment funding, and a green/yellow/red indicator per metric. Threshold guidance (standard personal-finance defaults, not YNAB rules): savings rate 20%+ green; carried credit card debt red when payment categories are underfunded; overspent categories yellow. Use as the opening move of a monthly review or 'how am I doing' question, then drill into specific tools. Costs about 4 API requests.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds that it 'combines' multiple data sources and discloses an approximate cost of 4 API requests, which is relevant for rate-limit expectations. This adds value beyond annotations, though no auth or other behavioral details are mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but each sentence earns its place: core components, thresholds, usage guidance, and cost. Information is front-loaded with the snapshot description before interpretation details. Slightly verbose with the threshold list but still efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description covers what the tool computes, how to interpret thresholds, when to use it, and an approximate cost. Nothing critical is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents the single optional parameter 'budgetId' with 100% coverage. The description does not add any semantic detail about the parameter beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('get') and resource ('budget health snapshot'), enumerates the components (month data, balances, trailing-3-month income/spending summary) and indicators (savings rate, age of money, etc.), and distinguishes it from sibling tools like get_budget or get_month by framing it as an aggregated opening move.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'opening move of a monthly review or how-am-I-doing question', and advises to 'then drill into specific tools', implying alternatives without needing to name them. The threshold guidance also helps the agent interpret results, which is part of using the tool correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_budget_settingsGet Budget SettingsARead-onlyIdempotent
Get a budget's settings: currency format (symbol, decimal digits, placement) and date format. Read-only. Use when formatting amounts or dates for display; not needed for tool inputs, which always use dollars and YYYY-MM-DD.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation read-only, idempotent, and non-destructive, so the description's 'Read-only' adds no new safety information. However, the description adds behavioral context beyond annotations: it clarifies that the output formats are for display only and that all tool inputs are in a fixed dollar/YYYY-MM-DD style, which helps the agent understand the tool's role without risking misuse.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The core purpose is front-loaded, the read-only note follows, and the usage guidance is packed into the second sentence. Every word contributes to help an agent decide to call this tool and understand its output.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with one optional parametercrazy and an output schema already present. The description covers its purpose, the exact fields returned, and when to use it versus not. There is no missing information an agent would need to invoke this tool correctly, and the presence of an output schema means return structure is already defined elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the single parameter 'budgetId' with its description ('Budget ID (uses default if not provided)') at 100% coverage. The tool description itself adds no additional meaning to the parameter, such as how the default budget is chosen or the expected format of the ID. With complete schema coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Get'), a specific resource ('a budget's settings'), and enumerates the exact contents (currency format with symbol, decimal digits, placement, and date format). This differentiates it from sibling tools like get_budget, which would return the budget object itself, and list_budgets, which returns all budgets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit when-to-use: 'Use when formatting amounts or dates for display.' It also provides a clear when-not-needed exclusion: 'not needed for tool inputs, which always use dollars and YYYY-MM-DD,' effectively telling the agent this tool is for display presentation, not for constructing API inputs. This is directly actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_categoryGet CategoryARead-onlyIdempotent
Get one category's full detail for the current month, including goal/target fields (type, target amount, funding progress). Read-only. Use for goal inspection; for a past or future month's numbers use get_month_category instead.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| categoryId | Yes | Category ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/non-destructive behaviorza. The description adds non-obvious context: the tool is scoped to the current month and includes goal/target fields, which is useful beyond what annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with the operation and scope, followed by routing guidance. No filler; the redundancy of 'Read-only' with annotations is minor and does not hurt clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only single-resource lookup with full schema coverage and an output schema, this description provides the necessary scope and routing context. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both budgetId and categoryId. The description adds contextual meaning about current-month data but no additional parameter-level format or behavior details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States it retrieves one category's full detail for the current monthches, explicitly mentioning goal/target fields. It clearly identifies the resource and scope, and differentiates from get_month_category.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use for goal inspection' and directs past/future month queries to get_month_category instead. This gives the agent a clear selection criterion and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_income_expense_summaryGet Income Expense SummaryARead-onlyIdempotent
Read-only income vs. spending summary by month, computed from transaction history. Income counts non-transfer inflows to 'Inflow: Ready to Assign'; spending counts non-transfer outflows; transfers and deleted transactions are excluded, so credit card payments do not double-count. Includes per-month savings rate ((income - spending) / income). Use for savings-rate reports, month-end closes, and trend questions like 'am I saving enough'. Refunds appear as negative spending months' offsets, not income.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| sinceDate | No | Start of the window (YYYY-MM-DD). Defaults to 6 full months back. | |
| untilDate | No | End of the window (YYYY-MM-DD). Defaults to today. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: it explains computation rules (income/spending definitions, exclusion of transfers and deleted transactions, savings-rate formula, refunds as negative spending offsets). The 'Read-only' wording is consistent with readOnlyHint=true, and the extra context about double-counting and refund handling is valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description earns its place: the core summary is front-loaded, followed by precise counting rules, the savings-rate definition, explicit use cases, and an edge-case clarification about refunds. The five sentences are justified by the tool's computational complexity and remain tightly structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation here. The description covers the tool's purpose, exact calculation methodology, exclusions, refund behavior, and usage guidance, leaving no critical gap for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers all three parameters with clear descriptions and 100% coverage, so the baseline is 3. The tool description adds no parameter-level semantics beyond what the schema already states; it references monthly windows but does not detail date formatting or defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Read-only income vs. spending summary by month, computed from transaction history.' It further defines the exact income and spending scope (non-transfer inflows/outflows) and clearly differentiates this tool from siblings like get_transactions or get_budget_health by focusing on monthly summary with savings-rate calculation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states applicable contexts: 'Use for savings-rate reports, month-end closes, and trend questions like
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_money_movement_groups_by_monthGet Money Movement Groups By MonthARead-onlyIdempotent
Get money movement groups (batched budget re-allocations) for one month. Read-only. The month-scoped view of list_money_movement_groups.
| Name | Required | Description | Default |
|---|---|---|---|
| month | Yes | Month in YYYY-MM-DD format (first of month), or 'current' | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is covered. The description adds useful context about the batched re-allocation nature and the month-scoped behavior. The 'Read-only' phrase is redundant with annotations, but the additional domain context earns credit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short and front-loaded, packing the core purpose into the first sentence. However, the standalone 'Read-only.' sentence adds little value because it merely repeats the readOnlyHint annotation, so it does not fully earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has only two parameters, a 100% documented schema, rich annotations, and an output schema. The description explains what money movement groups are, that they are month-scoped, and how this tool relates to its sibling. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both month and budgetId are already documented in the input schema. The description does not add any parameter-specific details beyond what the schema provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get money movement groups' with the qualifier 'for one month', and adds the clarifying parenthetical 'batched budget re-allocations'. It also explicitly distinguishes the tool as 'the month-scoped view of list_money_movement_groups', making it easy to differentiate from its sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates the tool is for retrieving money movement groups for a single month and references list_money_movement_groups as the broader alternative. It does not explicitly state 'when not to use' or list other alternatives, but the context is clear enough for an agent to select this tool for month-scoped queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_money_movements_by_monthGet Money Movements By MonthARead-onlyIdempotent
Get money movements (category-to-category budget re-allocations) for one month. Read-only. The month-scoped view of list_money_movements; use during month-end review to see how assignments were shuffled.
| Name | Required | Description | Default |
|---|---|---|---|
| month | Yes | Month in YYYY-MM-DD format (first of month), or 'current' | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive behavior; the description adds useful context by explaining that money movements are budget re-allocations and that this is a month-scoped, read-only view. There is no contradiction, and the extra domain context goes beyond what annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the action, clarifies the domain term, notes read-only behavior, and names the intended use case in two sentences. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, month-filtered retrieval tool, the description is complete: the annotations cover safety, the schema fully documents parameters, and an output schema exists. Nothing essential is missing for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with clear descriptions for both 'month' and 'budgetId'. The tool description adds the notion of month-scoping but does not provide parameter-specific detail beyond what the schema already states, which is acceptable but not additive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Get money movements') and immediately defines the domain term as 'category-to-category budget re-allocations.' It also distinguishes this tool from the sibling list_money_movements by explicitly framing it as the 'month-scoped view,' so an agent can clearly identify what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates when to use this tool ('during month-end review') and ties it to the broader list_money_movements tool, implying the monthly scoping as the deciding factor. It could be stronger by explicitly saying when not to use it, but the context is clear enough for correct selection among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_monthGet MonthARead-onlyIdempotent
Get one budget month's detail: month totals plus every category's budgeted/activity/balance and goal fields for that month (dollars). Read-only. The workhorse for monthly reviews and budget-vs-actual questions; combine with get_overspent_categories for the negative balances only.
| Name | Required | Description | Default |
|---|---|---|---|
| month | Yes | Month in YYYY-MM-DD format (first of month) | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description's 'Read-only' adds no new safety information beyond that. It does add useful scoping context (single month, all category fields, dollars), but no additional operational behavior such as pagination, errors, or side effects is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two densely informative sentences with no filler. The core scope and payload are front-loaded, the companion alternative is placed at the end, and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only getter with full schema coverage, rich annotations, and an output schema, the description is complete. It tells the agent what data it returns, when to use it, and which sibling tool complements it for a narrower use case.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented including month format and budgetId default behavior. The description adds contextual value by clarifying the result is for one budget month and expressed in dollars, but it doesn't meaningfully expand on parameter mechanics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Get one budget month's detail') and precisely enumerates the payload: month totals plus every category's budgeted/activity/balance and goal fields in dollars. This clearly differentiates it from sibling tools like get_month_category or list_months, which cover singular categories or month lists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly identifies this as 'the workhorse for monthly reviews and budget-vs-actual questions,' giving an agent a clear trigger context. It also names get_overspent_categories as the companion for negative balances only, providing a concrete when-to-use versus when-not-to-use distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_month_categoryGet Month CategoryBRead-onlyIdempotent
Get category budget for a specific month
| Name | Required | Description | Default |
|---|---|---|---|
| month | Yes | Month in YYYY-MM-DD format (first of month) | |
| budgetId | No | Budget ID (uses default if not provided) | |
| categoryId | Yes | Category ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety and idempotency are clear. The description adds no additional behavioral context such as what 'category budget' means, how missing data is handled, or whether it includes activity. It is consistent with annotations but does not go beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no fluff. It front-loads the core action and context, making it immediately understandable. It is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full schema, annotations, and an output schema present, the description is sufficient for an agent to call this tool correctly. It could mention the meaning of 'category budget' or edge cases, but given the rich structured metadata, the missing detail is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters (month, budgetId, categoryId) are documented in the schema. The description does not add any parameter-specific semantics beyond what the schema provides, meeting the baseline of 3 for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Get') and resource ('category budget') with a context ('for a specific month'), which distinguishes it from generic tools like get_category or get_month. It is not a tautology; it adds the month qualifier. However, it does not explicitly contrast with sibling tools, leaving some differentiation to the schema and naming.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives such as get_category, get_month, or get_overspent_categories. The description only states what it does without any context on selection criteria, exclusions, or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_overspent_categoriesGet Overspent CategoriesARead-onlyIdempotent
Get all categories with a negative balance for a given month. Use this to find prior-month overspends that are silently reducing the current month's Ready to Assign.
| Name | Required | Description | Default |
|---|---|---|---|
| month | Yes | Month in YYYY-MM-DD format (first of month) | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds behavioral context by explaining the significance of the returned data ('silently reducing the current month's Ready to Assign') and the temporal scope ('prior-month overspends'). This enriches the agent's understanding without contradicting any annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero wasted words. The primary purpose is stated first, followed immediately by the practical use case. The description is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema is present, so the return format is covered. The description explains the tool's purpose and use-case clearly. For a simple tool with only two parameters (one required), the description is sufficient. It does not discuss edge cases or the default budgetId behavior, but these are minor given the schema and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (month and budgetId) are already documented in the schema. The description only references the month parameter implicitly via 'for a given month' but adds no syntax or format details beyond what the schema provides. The baseline of 3 applies because the schema handles the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), a resource ('all categories with a negative balance'), and a temporal scope ('for a given month'). It clearly conveys the tool's function. While it doesn't explicitly contrast with sibling tools like get_month_category, the phrasing 'all categories' and the focus on negative balance make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear use case: 'Use this to find prior-month overspends that are silently reducing the current month's Ready to Assign.' This tells the agent when to apply the tool. It does not list alternatives or exclusion conditions, but the context is sufficiently specific for the agent to infer appropriateness.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_payeeGet PayeeARead-onlyIdempotent
Get one payee by ID (name, transfer_account_id, deleted flag). Read-only. Mostly useful to confirm a payee still exists or resolve its transfer account; for discovery use search_payees.
| Name | Required | Description | Default |
|---|---|---|---|
| payeeId | Yes | Payee ID | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond annotations by specifying the returned fields and the practical purpose, though it does not discuss not-found behavior or auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two compact sentences, front-loading the operation and scope before naming the alternative. Every sentence contributes either capability, intent, or routing guidance, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only get-by-ID tool, the description covers purpose, use case, alternative selection, returned fields, and read-only nature. The presence of an output schema means return-value details need not be repeated, and annotations cover side-effect safety, making the description complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with 'Payee ID' and 'Budget ID (uses default if not provided)' already documenting both parameters. The tool description adds no further parameter-level detail, so the schema carries the burden and a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get one payee by ID') and names the key returned fields: name, transfer_account_id, deleted flag. It also distinguishes itself from the discovery-oriented sibling by pointing to search_payees, preventing confusion with list_payees or get_payee_location.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly describes when to use the tool: to confirm a payee still exists or resolve its transfer account. It also names the alternative, search_payees, for discovery use cases, giving the agent clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_payee_locationGet Payee LocationARead-onlyIdempotent
Get one payee location record by its ID (payee, latitude, longitude). Read-only; requires a payee-location ID from list_payee_locations.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| payeeLocationId | Yes | Payee location ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly states 'Read-only', which aligns with and reinforces the annotations (readOnlyHint=true, destructiveHint=false). It adds context about the required input source (from list_payee_locations), which is useful behavioral information beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core function, includes the return fields, and notes the read-only nature. Every word earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-record retrieval tool with an output schema present, the description is complete. It covers the input requirement, the read-only nature, and the return fields. The only minor gap is not describing error behavior (e.g., what happens if the ID doesn't exist), but that's not critical for a read-only getter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description adds minimal parameter meaning beyond the schema, but it does clarify that payeeLocationId is the primary identifier and that budgetId is optional (uses default). This is baseline 3 territory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Get one payee location record by its ID' with the specific fields (payee, latitude, longitude). It distinguishes itself from sibling tools like list_payee_locations and get_payee_locations_by_payee by specifying it retrieves a single record by ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states it requires a payee-location ID from list_payee_locations, providing clear context on when to use this tool. It doesn't explicitly exclude alternatives, but the single-record-by-ID scope is clear enough to differentiate from list operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_payee_locations_by_payeeGet Payee Locations By PayeeARead-onlyIdempotent
Get all recorded GPS locations for one payee. Read-only. Useful to confirm which physical merchant an ambiguous payee refers to; empty for payees never used in YNAB's mobile app.
| Name | Required | Description | Default |
|---|---|---|---|
| payeeId | Yes | Payee ID | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the description's 'Read-only' is redundant. However, it adds valuable behavioral context by stating that results are empty for payees never used in YNAB's mobile app, which is not covered by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core action. It contains three sentences, but the 'Read-only' phrase is redundant given the annotations, slightly reducing efficiency. Still, every other part contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and safety annotations, the description covers the essential aspects: purpose, use case, and edge-case behavior (empty result). It does not explain return format, but that is delegated to the output schema, so it is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both parameters already documented in the input schema. The description does not add any additional parameter-specific semantics, so it stays at the baseline for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (Get) and resource (all recorded GPS locations for one payee), making the purpose obvious. It also specifies the scope 'for one payee,' which helps differentiate from list_payee_locations, though it does not explicitly name that sibling tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete use case ('confirm which physical merchant an ambiguous payee refers to'), which implies when to use it. However, it does not mention when not to use it or point to alternative tools like list_payee_locations or get_payee_location, so guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scheduled_transactionGet Scheduled TransactionARead-onlyIdempotent
Get one scheduled (recurring) transaction by ID: next date, frequency, amount (dollars), payee, category. Read-only. Composite realized-transaction IDs (uuid_YYYY-MM-DD) are not valid here — strip the date suffix or use get_transaction, which handles them.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| scheduledTransactionId | Yes | Scheduled transaction ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive. The description adds meaningful beyond-annotation context: the ID format restriction and the list of returned fields. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: purpose and output first, then the exclusion/fallback. Zero filler, perfectly front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-get read tool with an output schema available, everything an agent needs is covered: what it does, valid inputs, and when to use an alternative. Nothing missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds critical nuance about the ID format (not composite) and clarifies what is returned, exceeding what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description specifies a clear verb+resource ('Get one scheduled (recurring) transaction by ID'), lists the exact fields returned, and explicitly contrasts with get_transaction. This distinguishes it from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when NOT to use this tool (composite IDs are invalid) and provides the alternative (use get_transaction). This is concrete, actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transactionGet TransactionARead-onlyIdempotent
Get a single transaction by ID. The argument is 'transactionId' (not 'id'). Automatically handles composite scheduled-transaction IDs (e.g. uuid_YYYY-MM-DD): the date suffix is stripped before the lookup. If a composite ID's underlying matched transaction has been deleted, falls back to returning the active scheduled-transaction template wrapped in a marker shape { resource_type: 'scheduled_transaction', reason: 'composite_id_with_no_matched_transaction', scheduled_transaction, requested_id } so callers can distinguish the two return shapes. Non-composite IDs preserve strict behavior: a 404 still surfaces as resource_not_found.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| transactionId | Yes | Transaction ID |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds substantial behavioral detail: automatic composite ID handling, fallback to scheduled-transaction template with a marker shape, and strict behavior for non-composite IDs. It also clarifies the exact return shapes and error behavior, going well beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place. It front-loads the core purpose, then details composite handling and return shapes. No fluff, well-structured, and easy to parse despite its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (composite IDs, fallback behavior, two return shapes), the description is thorough. The output schema covers return values, and the description covers all edge cases and special handling. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds crucial semantics: it explicitly warns that the argument is 'transactionId' (not 'id'), explains the composite ID format and stripping, and describes the fallback logic. This adds meaning that the schema alone doesn't provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Get a single transaction by ID' – a specific verb and resource. It clearly differentiates from siblings like get_transactions and search_transactions by focusing on a single transaction via ID, and even clarifies the argument name. No ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (single transaction lookup) but doesn't explicitly name alternatives. However, it provides critical context on composite vs. non-composite IDs, which guides appropriate usage. It's clear enough for an agent to infer the right tool, though explicit exclusions would push it to a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transactionsGet TransactionsARead-onlyIdempotent
List transactions with filters: type ('unapproved' / 'uncategorized'), one of accountId / categoryId / payeeId, month, sinceDate, untilDate (YNAB defaults an omitted sinceDate to one year ago). Rows include import_payee_name_original, the raw bank string, for payee disambiguation. Without a delta request the result is capped at 500 rows (override with limit, up to 2000; page with offset); a capped result returns { transactions, total, returned, offset, has_more, next_offset } instead of a bare array. Prefer search_transactions to find specific rows.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by approval/categorization status | |
| limit | No | Row cap (default 500, max 2000). Ignored for delta requests. | |
| month | No | Filter by month (YYYY-MM-DD, first of month) | |
| offset | No | Rows to skip, in YNAB's date-ascending order; pass next_offset from a capped result. | |
| payeeId | No | Filter by payee ID | |
| budgetId | No | Budget ID (uses default if not provided) | |
| accountId | No | Filter by account ID | |
| sinceDate | No | Only return transactions on or after this date (YYYY-MM-DD). If omitted, YNAB defaults to one year ago. | |
| untilDate | No | Only return transactions on or before this date (YYYY-MM-DD) | |
| categoryId | No | Filter by category ID | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns { transactions, server_knowledge } uncapped. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds substantial behavioral detail beyond that: the 500-row default cap with limit/offset pagination, the changed response shape when capped (returning metadata fields), and the YNAB default of sinceDate to one year ago. This gives the agent accurate expectations for pagination and response handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, payee disambiguation detail, pagination rules and response shape, and a routing recommendation. It is front-loaded with the core purpose and filters, then progressively adds operational details. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters, an output schema, and the presence of sibling tools, the description covers the essential operational aspects: filters, pagination, response format differences, and the default date behavior. The output schema handles return details, and annotations cover safety. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all 11 parameters, so the schema already explains each parameter. The description adds extra semantics for key parameters: the default behavior of sinceDate, the fact that limit is ignored for delta requests, and that offset follows YNAB's date-ascending order. These enrich the schema without repeating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('transactions'), enumerates the available filters, and explicitly contrasts with the sibling search_transactions by saying 'Prefer search_transactions to find specific rows.' This gives an agent a clear, distinct purpose without needing to open the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly says to prefer search_transactions for finding specific rows, which is an explicit alternative and a when-not-to-use condition. It also implies usage for filtered listing via the enumerated filters. However, it does not contrast with get_transaction (single transaction retrieval) or other list_* siblings, so the routing guidance is not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userGet UserARead-onlyIdempotent
Get the authenticated YNAB user (their user ID). Read-only; takes no input. Mainly useful to verify the API token works — for credential/config diagnostics prefer ynab_auth_status, which needs no API request.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the useful context that this tool exists primarily to verify the API token works, which is behavioral context beyond the annotations. No contradiction; 'Read-only' aligns with readOnlyHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste; the purpose is front-loaded and the alternative is named in the second sentence. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema (which documents return values) and annotations covering the safety profile, the description covers purpose, usage, and the routing decision. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100%, so there is nothing for the description to document. The description confirms 'takes no input,' which matches the empty schema. Baseline 4 applies for a zero-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Get the authenticated YNAB user (their user ID)') and specifies the exact output (user ID). It distinguishes itself from the key sibling ynab_auth_status by framing its purpose as token verification, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative (ynab_auth_status) and the condition that selects it ('for credential/config diagnostics prefer ynab_auth_status'), noting it needs no API request. This is explicit when-to-use vs. when-not-to-use guidance with a concrete sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsList AccountsARead-onlyIdempotent
List all accounts in a budget with balances (dollars), type, closed/on-budget status, last-reconciled time, and debt metadata. Read-only. Use to find account IDs for transaction tools, check balances, or spot direct-import errors (direct_import_in_error). Includes closed accounts; filter on 'closed' if you only want active ones.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns { accounts, server_knowledge }. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds value by noting closed accounts are included, the direct_import_in_error field, and the returned metadata. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: the core action comes first, followed by read-only clarification, use cases, and a helpful note about closed accounts. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with full schema coverage holes and a defined output schema, this description is complete. It tells the agent what will be returned, that closed accounts are included, and how it should be used.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both budgetId and lastKnowledgeOfServer are already clearly described in the schema. The description adds no additional parameter-specific meaning beyond high-level context, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb and resource: 'List all accounts in a budget', and enumerates the exact fields returned (balances, type, status, last-reconciled time, debt metadata). It clearly distinguishes this tool from singular get_account and other list siblings by scope and content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States concrete use cases: finding account IDs for transaction tools, checking balances, and spotting direct-import errors. It also gives a filtering caveat for closed accounts. It does not explicitly contrast with get_account or other list tools, but the provided context is sufficient for a straightforward list operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_budgetsList BudgetsCRead-onlyIdempotent
List all budgets. Use a budget ID from the results in other tools, or omit budgetId to use the last-used budget.
| Name | Required | Description | Default |
|---|---|---|---|
| includeAccounts | No | If true, include each budget's account list in the response |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false) fully cover the safety profile. The description adds no additional behavioral context beyond the schema and annotations; it doesn't mention pagination, ordering, or other side effects. The mention of 'last-used budget' implies state but is irrelevant given budgetId is not a parameter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short (two sentences), but the second sentence contains inaccurate and unnecessary information about budgetId. While brevity is good, the inclusion of a non-existent parameter makes the structure less helpful and could cause the agent to attempt invalid calls.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one parameter, no required fields) and has an output schema, so the description doesn't need to explain return values. However, the misleading budgetId reference creates a gap in understanding—an agent cannot reliably know that the tool does not accept budgetId. This makes the description incomplete and potentially harmful.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description references a 'budgetId' parameter that does not exist in the input schema, which actively misleads the agent. For the actual parameter includeAccounts, the schema already provides a complete description, so the description adds no value. The false budgetId reference is a serious flaw, lowering the score significantly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The core purpose is clear: 'List all budgets' specifies the verb and resource. It distinguishes from get_budget by implying a collection. However, the second sentence introduces a budgetId parameter that is not in the schema, which muddies the purpose and could confuse an agent about the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives usage guidance about using a budget ID from results or omitting budgetId for last-used budget, but the input schema only defines includeAccounts and has no budgetId parameter. This is misleading and does not help an agent decide when to use this tool vs alternatives like get_budget. No explicit when-to-use or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_categoriesList CategoriesARead-onlyIdempotent
List all category groups and their categories with budgeted/activity/balance amounts (dollars) for the current month. Read-only. Use to find category IDs and survey the budget structure; for a specific month's numbers use get_month, and for name-based lookup use search_categories. Hidden, deleted, and YNAB-internal items (e.g. Credit Card Payments, Internal Master Category) are included with 'hidden' / 'deleted' / 'internal' flags — filter on them when presenting.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns { category_groups, server_knowledge }. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/safe, so the description's main added behavior is that hidden, deleted, and YNAB-internal items are included with flags. The current-month scope and the instruction to filter on flags provide useful behavior beyond the structured fields. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and contains the alternative tools and hidden-item behavior in a compact form. 'Read-only' is slightly redundant with the annotations, but the four sentences are otherwise dense and useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter, read-only list tool with a full output schema and 100% parameter documentation, the description is complete. It covers scope, alternatives, return contents, and special items, so an agent can invoke it correctly without digging further.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both optional parameters. The description doesn't add parameter-level detail beyond that, which is acceptable under the baseline for fully documented schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and object: 'List all category groups and their categories with budgeted/activity/balance amounts (dollars) for the current month.' It clearly distinguishes this from get_month and search_categories by naming those siblings, and it does not just restate the title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit use cases: find category IDs and survey the budget structure. It names get_month for a specific month's numbers and search_categories for name-based lookup, and it tells the agent to filter hidden/deleted/internal items when presenting. This leaves no ambiguity about when to select this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_money_movement_groupsList Money Movement GroupsARead-onlyIdempotent
List all money movement groups — batches of related money movements applied together (e.g. one multi-category re-allocation). Read-only. Join to list_money_movements rows via money_movement_group_id.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description explicitly states 'Read-only', which matches. It adds semantic context by defining what a money movement group represents and how to join to movements, which goes beyond the structured fields. It does not cover pagination or ordering, but the output schema exists and the safety profile is clear, so this is solid coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, with the primary action ('List all money movement groups') front-loaded, followed by a clarifying definition and a join hint. There is zero redundant phrasing; every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with an output schema and annotations covering safety, the description is largely complete: it defines the domain concept, states read-only behavior, and explains how to connect to related data. The only notable gap is not mentioning the sibling get_money_movement_groups_by_month, which could be the intended tool when filtering by month; however, this is a minor omission given the overall clarity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% coverage for the single optional parameter budgetId, including its description ('Budget ID (uses default if not provided)'). The description adds no additional meaning about the parameter—it does not even mention budgetId. Baseline of 3 is appropriate since the schema already documents the parameter completely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'all money movement groups', and defines what a group is (batches of related money movements applied together). It also gives a concrete example (multi-category re-allocation), which distinguishes it from list_money_movements by implying the join relationship. This is a specific, unambiguous purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to relate this tool to list_money_movements via the join key, but it does not explicitly state when to use this tool versus get_money_movement_groups_by_month or other sibling tools. The usage context is implied (general list-all), but no explicit alternatives or exclusions are given, so it stops short of full guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_money_movementsList Money MovementsARead-onlyIdempotent
List all money movements — the history of budget re-allocations between categories (who moved how much from where to where, when). Read-only. Use to answer 'why did this category's assigned amount change'; these are budget moves, not transactions. Can be long on old budgets; prefer get_money_movements_by_month for a specific month.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, and idempotentHint, so the safety profile is covered. The description adds a performance warning ('can be long on old budgets') and clarifies the semantic distinction from transactions, which is valuable beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The core purpose is stated first, followed by usage guidance and a performance note. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the presence of annotations covering safety, and an output schema, the description fully covers purpose, usage, and performance caveats. Nothing essential is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a single optional parameter budgetId that is self-explanatory in the schema. The description does not add parameter-specific guidance, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb 'List' and resource 'money movements' with a clear definition of what they are (history of budget re-allocations) and explicitly distinguishes from transactions. It also names a sibling tool for scoped queries, making it unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit use case ('why did this category's assigned amount change') and an explicit exclusion (these are not transactions). It also advises preferring get_money_movements_by_month for a specific month, giving clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_monthsList MonthsARead-onlyIdempotent
List all budget months with summary numbers per month (income, budgeted, activity, Ready to Assign, age of money — dollars). Read-only. Use to find which months exist and their headline totals; for per-category detail in one month use get_month.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns { months, server_knowledge }. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds contextual value by explaining the dollar-unit summary metrics and the tool's scope across all months, which goes slightly beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two well-structured sentences with no wasted words. The core behavior is stated first, followed by a precise routing note to the alternative tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool with an output schema, rich annotations, and optional parameters, the description fully covers what an agent needs to select and call it correctly. The delta parameter behavior is documented in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents both parameters. The description does not elaborate on parameter behavior beyond what the schema provides, meriting the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a precise resource ('all budget months') and enumerates the summary fields returned. It clearly differentiates from the sibling get_month by noting this is the month-level overview tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool ('find which months exist and their headline totals') and names the alternative for per-category detail ('use get_month'). This gives an agent clear routing guidance with no inference needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_payee_locationsList Payee LocationsARead-onlyIdempotent
List all payee locations (GPS coordinates YNAB's mobile app recorded at transaction time). Read-only. Only payees with mobile-recorded transactions appear; many budgets have none. Use get_payee_locations_by_payee to scope to one payee.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, so the bar is lower. The description adds behavioral context beyond annotations by disclosing the filtering rule ('only payees with mobile-recorded transactions appear') and data provenance ('GPS coordinates... recorded at transaction time'). This helps set expectations for empty results and data scope.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose, behavioral caveat, and alternative routing. No filler or redundancy. Front-loaded with the key action and context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional param, output schema present, annotations complete), the description covers the essential interpretation, result-sparsity behavior, and sibling differentiation. Nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers the sole optional parameter budgetId fully with 'Budget ID (uses default if not provided)', so baseline is 3. The description does not elaborate on parameter semantics, but the schema handles it completely; no additional meaning is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List all payee locations (GPS coordinates YNAB's mobile app recorded at transaction time).' It clearly distinguishes from sibling get_payee_locations_by_payee by noting the all-scope and by explicitly naming the scoped alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: 'Only payees with mobile-recorded transactions appear; many budgets have none' warns about result sparsity, and 'Use get_payee_locations_by_payee to scope to one payee' tells the agent exactly when to use the sibling instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_payeesList PayeesARead-onlyIdempotent
List all payees with IDs and transfer_account_id (non-null marks a transfer payee — use it as payeeId when creating transfers instead of inventing a 'Transfer : ...' name). Read-only. For name-based lookup prefer search_payees; payee lists on mature budgets can be long.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns { payees, server_knowledge }. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds significant behavior beyond that: the meaning of non-null transfer_account_id, the recommendation to use it as payeeId instead of inventing names, and the warning about list size. These are critical operational details not present in structured data and are highly relevant to correct invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: the first states the core function and key output field, the second adds the transfer payee nuance, the third routes to the alternative and warns about volume. No filler, no repetition; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, full schema coverage, present output schema, and comprehensive annotations, the description provides all essential context. It covers the key output semantics (transfer payee), the performance characteristic, and the alternative tool. Nothing an agent needs to correctly select and call this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (budgetId, lastKnowledgeOfServer) are fully documented in the schema. The description does not add any new parameter-level meaning beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List all payees with IDs and transfer_account_id'), distinguishes from siblings like search_payees and get_payee, and clarifies the critical transfer payee field. An agent can immediately understand what this tool does and how it differs from related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly directs users to search_payees for name-based lookup and warns about long lists on mature budgets. It also instructs how to use transfer_account_id as payeeId for transfers, which tells the agent when to use this output. This is direct, actionable guidance on when to choose this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_scheduled_transactionsList Scheduled TransactionsARead-onlyIdempotent
List all scheduled (recurring) transactions. NOTE: only manually-created recurring entries appear here — auto-imported recurring charges (subscriptions, utilities, insurance) are NOT included. Use prior-month transaction history to identify recurring charge timing instead.
| Name | Required | Description | Default |
|---|---|---|---|
| budgetId | No | Budget ID (uses default if not provided) | |
| lastKnowledgeOfServer | No | Delta request server knowledge. When provided, returns { scheduled_transactions, server_knowledge }. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly and idempotent behavior. The description adds critical behavioral context beyond those: the returned set excludes auto-imported recurring entries, which materially changes how an agent should interpret results. This prevents a subtle misuse that annotations alone cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the core purpose first, then the essential caveat the agent must know, then the fallback behavior. Every sentence carries important information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich output schema, 100% parameter documentation, and safety annotations, the description covers the only significant gap: what class of items is actually included. The warning plus alternative makes the tool fully actionable for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters (budgetId, lastKnowledgeOfServer) already have meaningful descriptions. The tool description does not add parameter-level detail, which is acceptable under the baseline for fully documented schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('List all scheduled (recurring) transactions') and immediately clarifies the exact scope: only manually-created recurring entries. This distinguishes it both from get_scheduled_transaction and from detection of auto-imported recurring charges, leaving no ambiguity about what the tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when the tool should NOT be used—for auto-imported recurring charges such as subscriptions, utilities, and insurance—and gives an actionable alternative: use prior-month transaction history to identify those recurring charge timings. This is clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_undo_historyList Undo HistoryARead-onlyIdempotent
List the local undo journal: every write this MCP server performed (most recent first), with per-entry undo capability. Read-only; reads a local journal file, never the YNAB API. Use this to review what changed before calling undo_operation, or to audit a session's writes. Entries with undoable:false are recorded for audit only and cannot be reversed automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum entries to return (default 20, newest first) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds valuable context beyond annotations: it reads a local journal file, never the YNAB API, returns most recent first, and explains the meaning of undoable:false. This is transparent and consistent with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences with no wasted words. The core purpose and ordering are front-loaded, followed by the read-only distinction, usage guidance, and the undoable:false caveat. Every sentence contributes necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only tool with a rich description, an output schema, and safety annotations, this is complete. The description covers behavior, source, ordering, use cases, and a key edge condition; return format is covered by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the only parameter, limit, already has a full description including default and maximum. The tool description doesn't add further parameter semantics, so the baseline 3 applies given the schema handles the documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List the local undo journal' with clear scope ('every write this MCP server performed'). It distinguishes itself from YNAB API tools by explicitly saying it reads a local journal file and never the YNAB API, making sibling differentiation unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use cases: review before calling undo_operation, or audit a session's writes. It also clarifies the limitation that entries with undoable:false are only for audit and cannot be reversed, giving agents actionable guidance on when the tool is useful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
review_unapprovedReview UnapprovedARead-onlyIdempotent
Unapproved transactions across all history, split into ready_to_approve (categorized, split, or transfer; grouped by payee) and needs_category_first. Each row carries flags: manually_entered, match_broken (cosmetic; the row is still editable), scheduled_transaction_realized (composite id, writable), new_payee, no_prior_amount_match, category_drift:was_X. Group headers report category_names and mixed_categories (category_name is null when mixed) and a net total with inflow_total/outflow_total when signs are mixed; see resource ynab://guide/flags-reference. Large queues: summary:true returns counts and per-payee aggregates; compact:true keeps ids and essentials only. Above maxTransactions rows (default 400) the response drops to compact, then summary, and reports mode.
| Name | Required | Description | Default |
|---|---|---|---|
| compact | No | If true (and summary is not set), keep per-transaction rows but only the fields needed to act (id, date, payee_name, amount, category_name, account_name, flags; matched_transaction_id for match_broken rows). | |
| summary | No | If true, omit per-transaction details from the response and return only counts + by-payee aggregates (for both ready_to_approve and needs_category_first). Use this when the full unapproved queue is large; drill into specifics with get_transactions afterwards. | |
| budgetId | No | Budget ID (uses default if not provided) | |
| maxTransactions | No | Above this many unapproved rows (default 400) a full response degrades to compact, and above twice it to summary; the response reports mode and a notice. Raise it to force detail. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the readOnlyHint/idempotentHint annotations: it explains flag semantics (match_broken is cosmetic and row remains editable, scheduled_transaction_realized is writable), degradation behavior (compact/summary fallback above thresholds), and response grouping details. This enriches the agent's understanding without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured, front-loading the core purpose and then logically detailing flags, grouping, and degradation. Every sentence adds unique value, and the use of semicolons and clauses keeps it readable. It is appropriately sized for the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists (as indicated) and annotations cover safety, the description covers all necessary aspects: the categories, flags, grouping headers, degradation modes, and references to a flags reference. An agent can invoke the tool correctly and interpret the response without ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 100% schema coverage, the description adds meaningful semantics: it explains the effect of summary:true and compact:true, the degradation logic tied to maxTransactions, and the default of 400. These behavioral details are not in the schema, significantly enhancing parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Unapproved transactions across all history', split into ready_to_approve and needs_category_first. It specifies the resource (unapproved transactions) and the action (review), distinguishing it from sibling tools like get_transactions or search_transactions. The verb and scope are explicit and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool (reviewing unapproved transactions) and explains parameter usage for large queues (summary:true, compact:true, maxTransactions). However, it does not explicitly mention alternatives or when not to use it, leaving the selection among siblings to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_categoriesSearch CategoriesARead-onlyIdempotent
Search categories by name and category-group name (case-insensitive; multi-word queries are tokenized and OR-matched, ranked with whole-phrase and name hits first). Results report matched_on and matched_terms. No synonym expansion; if a search is empty, fall back to list_categories.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Category or group name to search for. Multi-word queries are OR-matched per word (e.g. 'work expenses' matches '💻 Work Expenses (Oliver LLC)' and anything in a 'Business Expenses' group). | |
| budgetId | No | Budget ID (uses default if not provided) | |
| includeHidden | No | If true, also search hidden categories and hidden category groups (default false). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, and the description adds valuable context beyond that: case-insensitive matching, tokenized OR semantics, ranking order, matched_on/matched_terms reporting, and no synonym expansion. This gives an agent clear expectations about how results are produced and labeled. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences deliver the core matching behavior, ranking rules, result reporting, and a fallback instruction. Every clause earns its place, and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with a full output schema and annotations covering safety and idempotency, the description is complete. Required query behavior, matching edge cases, hidden-category handling in the schema, and fallback routing are all present, leaving no material gap for a correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description enriches the query parameter with important semantics: case-insensitivity, tokenization, OR matching, and ranking behavior. budgetId and includeHidden remain adequately documented in the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a precise verb-resource pair, "search categories", and narrows scope to name plus category-group name. It also names list_categories as the fallback, making the tool's role distinct from that sibling without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly gives an alternative and a condition: "if a search is empty, fall back to list_categories". It frames search as the lookup entry point, and the resource-specific wording naturally distinguishes it from search_transactions and search_payees.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_payeesSearch PayeesARead-onlyIdempotent
Search payees by partial name match (case-insensitive). Matching ignores HTML entity escaping, so 'B&H' finds a payee YNAB stores as 'B&H Photo Video'. Useful for finding payee IDs. Unlike search_categories this is a single substring match, not a tokenized OR — search one distinctive word at a time.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Partial payee name to search for | |
| budgetId | No | Budget ID (uses default if not provided) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety. The description adds meaningful behavioral context beyond annotations: case-insensitive matching, HTML entity unescaping (with a concrete example), and the substring-vs-tokenized distinction. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. The core behavior and the most important caveat (HTML entity handling) are front-loaded, followed by a usage note and a sibling comparison. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering the read-only/idempotent safety profile and an output schema present, the description sufficiently covers matching behavior, usage guidance, and the key sibling distinction. Nothing critical is missing for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters have basic descriptions. The description adds value beyond the schema by explaining the query semantics (partial, case-insensitive, HTML-entity-ignoring) and advising to search one word at a time. It doesn't clarify budgetId's default behavior beyond the schema, but the schema already says 'uses default if not provided'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Search payees'), a resource ('payees'), and a precise matching behavior (partial, case-insensitive, HTML-entity-ignoring). It explicitly differentiates from the sibling search_categories by contrasting substring match vs tokenized OR, so an agent can select it correctly without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says the tool is 'useful for finding payee IDs' and gives a concrete usage tip ('search one distinctive word at a time'), plus contrasts with search_categories. It doesn't explicitly state when NOT to use it or list alternatives beyond the one sibling, but the context is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_transactionsSearch TransactionsARead-onlyIdempotent
Search transactions by text and/or amount, with pagination. The server fetches the (optionally account- and date-bounded) transaction list from YNAB and filters it before responding, so a busy budget returns a small page instead of a multi-megabyte dump that can exceed client tool timeouts. 'query' is a case-insensitive substring match over payee_name, import_payee_name_original (raw bank string), memo, account_name, category_name, and split rows' payee/memo/category. 'amount' matches on absolute value with half-cent tolerance, so 12.34 finds a -12.34 outflow. Results are newest-first; page with limit/offset using the returned next_offset. Provide at least one of query or amount.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size (default 50, max 500) | |
| query | No | Text to find in payee, raw import payee, memo, account, or category (case-insensitive substring) | |
| amount | No | Amount in dollars to match on absolute value (12.34 matches -12.34 and 12.34) | |
| offset | No | Number of matches to skip (default 0); pass next_offset from the previous page | |
| budgetId | No | Budget ID (uses default if not provided) | |
| accountId | No | Restrict the search to one account | |
| sinceDate | No | Only search transactions on or after this date (YYYY-MM-DD). If omitted, YNAB defaults to one year ago. | |
| untilDate | No | Only search transactions on or before this date (YYYY-MM-DD) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite strong annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false), the description adds substantial behavioral detail: the server fetches and filters locally, query is a case-insensitive substring over specific fields, amount matches on absolute value with half-cent tolerance, results are newest-first, and pagination uses next_offset. This goes far beyond what the annotations alone communicate and is consistent with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then efficiently delivers high-value details: implementation rationale, field coverage, amount tolerance, ordering, pagination, and a required-argument constraint. Every sentence earns its place. It is detailed but not bloated, and the most important information appears first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex, eight-parameter tool, but the description covers the essential usage contract thoroughly: what is searched, how amount matching behaves, optional bounds, result ordering, pagination, and the minimum-argument requirement. An output schema exists for return shapes, and annotations cover safety, so no critical operational context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but the description still adds crucial meaning: the exact set of fields query searches, the absolute-value half-cent tolerance for amount, the account/date bounding behavior, and the requirement to provide at least one of query or amount. It also explains the limit/offset pagination contract with next_offset, enriching the schema's otherwise mechanical parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Search transactions by text and/or amount, with pagination.' It clearly differentiates this from listing tools by emphasizing text/amount filtering and pagination, and even details the exact fields searched. An agent can immediately identify what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for use: it filters a potentially large YNAB transaction list and returns a small page, explicitly advising against multi-megabyte dumps that could exceed timeouts. It also states the requirement 'Provide at least one of query or amount' and explains pagination via next_offset. It does not explicitly name a sibling alternative such as get_transactions when no filtering is needed, so it stops short of a full when-to-use/when-not-to-use contrast.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ynab_auth_statusYNAB Auth StatusARead-onlyIdempotent
Check whether the YNAB MCP server has credentials configured and whether write tools are enabled.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds specific context about checking credentials and write-tool enablement, which is useful beyond the generic annotations. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single, clear sentence with no wasted words. Verb and resource are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and no parameters, the description covers the essential purpose. It's complete for a status-check tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, so schema coverage is trivially complete. Baseline score of 4 applies as the description doesn't need to add parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (Check) and resource (YNAB MCP server credentials and write tools enabled), clearly distinguishing it from the data-retrieval siblings. The title and description align perfectly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description does not explicitly state when to use this tool vs alternatives, though it's clear it's a diagnostic status check. No exclusions or conditions are provided, but the purpose implicitly guides usage. Lacks explicit guidance on when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ynab_tool_executeExecute YNAB ToolARead-onlyIdempotent
Execute an existing read-only YNAB MCP tool by name. Use ynab_tool_index first to discover YNAB tool names, then pass the selected tool_name and its JSON input. Write-capable tools must be called directly or through ynab_write_tool_execute when YNAB_ALLOW_WRITES=1.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | JSON input for the selected YNAB tool. Omit or pass an empty object for tools that take no input. | |
| tool_name | Yes | Existing read-only YNAB tool name, such as review_unapproved, get_transactions, list_categories, search_categories, or search_payees. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description reinforces the read-only boundary while adding the routing behavior and the YNAB_ALLOW_WRITES condition. It does not describe failure behavior, but the output schema and annotations cover the main safety contract, so this is solid rather than exceptional.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with the core purpose first, then the usage workflow, then the write-tool exception. Every sentence earns its place and no words are wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic dispatcher, the description covers discovery, parameter passing, the read-only restriction, and the alternative path for write tools. With output schema and rich annotations present, nothing essential is missing for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents tool_name with examples and input and describes input as an optional JSON object. The description adds workflow context (use index first) but no additional parameter semantics beyond what the schema provides, making baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action—'Execute an existing read-only YNAB MCP tool by name'—and immediately separates this dispatcher from ynab_tool_index (discovery) and from direct write tools. This gives an agent a clear model of what the tool does and what it is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent to call ynab_tool_index first, then pass tool_name and JSON input, and it names the alternative path for write-capable tools (direct call or ynab_write_tool_execute when YNAB_ALLOW_WRITES=1). This is concrete when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ynab_tool_indexYNAB Tool IndexARead-onlyIdempotent
Discover the YNAB MCP server tools. Use this when you need YNAB budgets, accounts, categories, payees, transactions, scheduled transactions, unapproved transaction review, approval, or budget cleanup tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the agent knows this is a safe, non-destructive operation. The description adds that the tool discovers available server tools, which is consistent with the annotations but does not add much beyond the title and the obvious meta-tool behavior. There is no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. It opens with the action and object, then lists the relevant domains. Every word contributes to helping an agent decide whether to call this tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter discovery tool with rich annotations and an output schema, the description is complete. It tells the agent exactly when to use the tool, what domains are covered, and the tool's safe read-only nature is already captured by annotations. No return-value explanation is necessary because an output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and schema description coverage is 100%, so there are no parameter details that need compensation. The baseline of 4 applies because there is nothing to document; the description does not need to add parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Discover the YNAB MCP server tools.' It enumerates specific domain areas such as budgets, accounts, categories, payees, transactions, and cleanup tools, distinguishing it from the sibling tools that perform those operations directly. The verb 'Discover' plus the resource makes the meta-tool nature obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: 'Use this when you need YNAB budgets, accounts, categories, payees, transactions, scheduled transactions, unapproved transaction review, approval, or budget cleanup tools.' This tells an agent when to invoke the tool, though it does not explicitly name alternatives or state when not to use it. For an index/discovery tool, this is clear and sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
39 tool updates
v5.4.0- Changed
audit_account_reconciliation1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Audit Account Reconciliation."
- Changed
audit_credit_card_payments1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Audit Credit Card Payments."
- Changed
detect_recurring_charges1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Detect Recurring Charges."
- Changed
export_transactions2 fields changed- added
Input schema / properties / maxRowsAdded value: +{ + "description": "Row cap (default 500, max 2000). When exceeded, the newest rows are kept and a second text block reports the truncation.", + "maximum": 2000, + "minimum": 1, + "type": "integer" +} - removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Export Transactions."
- Changed
get_account1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Account."
- Changed
get_budget1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Budget."
- Changed
get_budget_health1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Budget Health."
- Changed
get_budget_settings1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Budget Settings."
- Changed
get_category1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Category."
- Changed
get_income_expense_summary1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Income Expense Summary."
- Changed
get_money_movement_groups_by_month1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Money Movement Groups By Month."
- Changed
get_money_movements_by_month1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Money Movements By Month."
- Changed
get_month1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Month."
- Changed
get_month_category1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Month Category."
- Changed
get_overspent_categories1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Overspent Categories."
- Changed
get_payee1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Payee."
- Changed
get_payee_location1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Payee Location."
- Changed
get_payee_locations_by_payee1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Payee Locations By Payee."
- Changed
get_scheduled_transaction1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Scheduled Transaction."
- Changed
get_transaction1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Transaction."
- Changed
get_transactions4 fields changed- changed
Input schema / properties / lastKnowledgeOfServer / descriptionPrevious value: -"Delta request server knowledge. When provided, returns { transactions, server_knowledge }."New value: +"Delta request server knowledge. When provided, returns { transactions, server_knowledge } uncapped." - added
Input schema / properties / limitAdded value: +{ + "description": "Row cap (default 500, max 2000). Ignored for delta requests.", + "maximum": 2000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Rows to skip, in YNAB's date-ascending order; pass next_offset from a capped result.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get Transactions."
- Changed
get_user1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Get User."
- Changed
list_accounts1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Accounts."
- Changed
list_budgets1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Budgets."
- Changed
list_categories1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Categories."
- Changed
list_money_movement_groups1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Money Movement Groups."
- Changed
list_money_movements1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Money Movements."
- Changed
list_months1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Months."
- Changed
list_payee_locations1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Payee Locations."
- Changed
list_payees1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Payees."
- Changed
list_scheduled_transactions1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Scheduled Transactions."
- Changed
list_undo_history1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by List Undo History."
- Changed
review_unapproved3 fields changed- changed
Input schema / properties / compact / descriptionPrevious value: -"If true (and summary is not set), keep per-transaction detail but return only the fields needed to act — id, date, payee_name, amount, category_name, account_name, flags — dropping bulky fields (import strings, subtransactions, import ids) that push the full response past the inline size limit. Rows flagged match_broken additionally keep matched_transaction_id, since triaging that flag means GETting the matched id. Use when you need transaction IDs to approve or recategorize but the full queue would overflow."New value: +"If true (and summary is not set), keep per-transaction rows but only the fields needed to act (id, date, payee_name, amount, category_name, account_name, flags; matched_transaction_id for match_broken rows)." - added
Input schema / properties / maxTransactionsAdded value: +{ + "description": "Above this many unapproved rows (default 400) a full response degrades to compact, and above twice it to summary; the response reports mode and a notice. Raise it to force detail.", + "maximum": 2000, + "minimum": 1, + "type": "integer" +} - removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Review Unapproved."
- Changed
search_categories1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Search Categories."
- Changed
search_payees1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Search Payees."
- Added
search_transactions - Changed
ynab_auth_status1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by YNAB Auth Status."
- Changed
ynab_tool_execute1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by Execute YNAB Tool."
- Changed
ynab_tool_index1 field changed- removed
Output schema / properties / result / descriptionRemoved value: -"Structured result returned by YNAB Tool Index."
17 tool updates
v5.2.0- Added
audit_account_reconciliation - Added
detect_recurring_charges - Added
export_transactions - Added
get_budget_health - Added
get_budget_settings - Added
get_money_movement_groups_by_month - Added
get_month - Added
get_month_category - Added
get_overspent_categories - Added
get_payee - Added
get_payee_location - Added
list_accounts - Added
list_categories - Added
list_money_movements - Changed
review_unapproved1 field changed- changed
Input schema / properties / compact / descriptionPrevious value: -"If true (and summary is not set), keep per-transaction detail but return only the fields needed to act — id, date, payee_name, amount, category_name, account_name, flags — dropping bulky fields (import strings, subtransactions, matched/import ids) that push the full response past the inline size limit. Use when you need transaction IDs to approve or recategorize but the full queue would overflow."New value: +"If true (and summary is not set), keep per-transaction detail but return only the fields needed to act — id, date, payee_name, amount, category_name, account_name, flags — dropping bulky fields (import strings, subtransactions, import ids) that push the full response past the inline size limit. Rows flagged match_broken additionally keep matched_transaction_id, since triaging that flag means GETting the matched id. Use when you need transaction IDs to approve or recategorize but the full queue would overflow."
- Changed
search_categories2 fields changed- added
Input schema / properties / includeHiddenAdded value: +{ + "description": "If true, also search hidden categories and hidden category groups (default false).", + "type": "boolean" +} - changed
Input schema / properties / query / descriptionPrevious value: -"Partial category name to search for (e.g. 'work' matches '💻 Work Expenses (Oliver LLC)')"New value: +"Category or group name to search for. Multi-word queries are OR-matched per word (e.g. 'work expenses' matches '💻 Work Expenses (Oliver LLC)' and anything in a 'Business Expenses' group)."
- Added
ynab_auth_status
34 tool updates
v5.1.1- Added
audit_credit_card_payments - Changed
get_account1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Account." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
get_budget2 fields changed- added
Input schema / properties / lastKnowledgeOfServerAdded value: +{ + "description": "Delta request server knowledge. When provided, returns changed entities and server_knowledge instead of the summary.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Budget." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Removed
get_budget_settings - Changed
get_category1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Category." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Added
get_income_expense_summary - Removed
get_money_movement_groups_by_month - Changed
get_money_movements_by_month1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Money Movements By Month." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Removed
get_month - Removed
get_month_category - Removed
get_overspent_categories - Removed
get_payee - Removed
get_payee_location - Changed
get_payee_locations_by_payee1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Payee Locations By Payee." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
get_scheduled_transaction1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Scheduled Transaction." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
get_transaction1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Transaction." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
get_transactions1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get Transactions." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
get_user2 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Get User." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Removed
list_accounts - Changed
list_budgets3 fields changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#" - added
Input schema / properties / includeAccountsAdded value: +{ + "description": "If true, include each budget's account list in the response", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by List Budgets." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Removed
list_categories - Changed
list_money_movement_groups1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by List Money Movement Groups." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Removed
list_money_movements - Changed
list_months1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by List Months." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
list_payee_locations1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by List Payee Locations." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
list_payees1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by List Payees." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
list_scheduled_transactions1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by List Scheduled Transactions." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Added
list_undo_history - Changed
review_unapproved1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Review Unapproved." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
search_categories1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Search Categories." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
search_payees1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Search Payees." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Removed
ynab_auth_status - Changed
ynab_tool_execute1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by Execute YNAB Tool." + } + }, + "required": [ + "result" + ], + "type": "object" +}
- Changed
ynab_tool_index1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "result": { + "description": "Structured result returned by YNAB Tool Index." + } + }, + "required": [ + "result" + ], + "type": "object" +}
5 tool updates
v3.1.0- Changed
get_transactions2 fields changed- changed
Input schema / properties / sinceDate / descriptionPrevious value: -"Only return transactions on or after this date (YYYY-MM-DD)"New value: +"Only return transactions on or after this date (YYYY-MM-DD). If omitted, YNAB defaults to one year ago." - added
Input schema / properties / untilDateAdded value: +{ + "description": "Only return transactions on or before this date (YYYY-MM-DD)", + "type": "string" +}
- Changed
review_unapproved1 field changed- added
Input schema / properties / compactAdded value: +{ + "description": "If true (and summary is not set), keep per-transaction detail but return only the fields needed to act — id, date, payee_name, amount, category_name, account_name, flags — dropping bulky fields (import strings, subtransactions, matched/import ids) that push the full response past the inline size limit. Use when you need transaction IDs to approve or recategorize but the full queue would overflow.", + "type": "boolean" +}
- Added
ynab_auth_status - Added
ynab_tool_execute - Added
ynab_tool_index
28 tool updates
v2.0.0- First observed
get_account - First observed
get_budget - First observed
get_budget_settings - First observed
get_category - First observed
get_money_movement_groups_by_month - First observed
get_money_movements_by_month - First observed
get_month - First observed
get_month_category - First observed
get_overspent_categories - First observed
get_payee - First observed
get_payee_location - First observed
get_payee_locations_by_payee - First observed
get_scheduled_transaction - First observed
get_transaction - First observed
get_transactions - First observed
get_user - First observed
list_accounts - First observed
list_budgets - First observed
list_categories - First observed
list_money_movement_groups - First observed
list_money_movements - First observed
list_months - First observed
list_payee_locations - First observed
list_payees - First observed
list_scheduled_transactions - First observed
review_unapproved - First observed
search_categories - First observed
search_payees
TDQS
Scored across 39 tools
Most tools have clearly distinct resource+action pairs (list/get/search variants), and descriptions explicitly guide selection (e.g. 'prefer search_transactions to find specific rows'). The main mild risk is the cluster of aggregate reporting tools (income/spending summary, budget health, recurring detection, audits) and get_transactions/search_transactions/export_transactions, but each has a distinct output or purpose.
The dominant pattern is verb_noun (list_budgets, get_category, search_payees, export_transactions, audit_credit_card_payments, detect_recurring_charges). Minor deviations include get_transactions instead of list_transactions, get_payee_locations_by_payee, and the ynab_tool_* meta tools, but these are readable and mostly predictable.
With 39 tools, the set feels heavy, especially since several are near-duplicate scoped variants (four money-movement tools, four payee-location tools, plus search and export variants). While the YNAB domain is broad, this count exceeds a comfortable size and many tools could be consolidated without losing clarity.
The server is heavily read-only: it covers lookup, search, audit, and reporting well, but there are no actual transaction/category/account write tools despite mentions of write capability and references to actions like update_month_category and approval. Core lifecycle operations for editing transactions, approving entries, or updating budgets are missing, which leaves significant workflow gaps.
Maintenance
Related MCP Connectors
- financeOAuthcom.zoninga
Personal finance for AI agents: accounts, budgets, goals, 9-strategy debt payoff, reports. OAuth 2.1
Chat with your bank data: balances, transactions, budgets, bills. Reads only, never moves money.
Read your accounts, budgets and net worth, and draft changes you confirm.
Personal-finance workspace for AI agents: accounts, spending, budgets, goals, and investments.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with YNAB budgets through natural language. Supports managing accounts, categories, transactions, and budget months with 21 tools for comprehensive budget operations.-
- AlicenseAqualityCmaintenanceEnables interaction with You Need A Budget (YNAB) through their API, allowing users to manage budgets, accounts, categories, transactions, payees, and scheduled transactions through natural language.1215 npm1GPL 3.0
- AlicenseBqualityCmaintenanceExposes YNAB API endpoints as MCP tools, allowing AI assistants to manage budgets, accounts, transactions, and more through natural language.4418 PyPI94MIT
- AlicenseAqualityBmaintenanceConnects AI assistants to YNAB budgets, providing over 30 tools for managing budgets, accounts, transactions, categories, and analytics with delta sync and caching.4750 PyPI38AGPL 3.0