YNAB MCP Server
The YNAB MCP Server connects AI assistants to your YNAB budget locally, translating natural language into budget queries and operations. It is read-only by default, with write capabilities requiring explicit YNAB_ALLOW_WRITES=1 opt-in. All monetary values are handled in dollars (not YNAB's internal milliunits).
Read Capabilities (default):
User & Budget: Get user info, list budgets, retrieve budget summaries/settings
Accounts: List all accounts with balances and debt details, or get a specific account
Categories: List all category groups/categories (with budgeted/activity/balance), get monthly category data, search by partial name (e.g., "groc" → "Groceries")
Payees: List payees, get specific payees, search by partial name, retrieve GPS payee locations
Budget Months: List months with income/activity/to-be-budgeted/age-of-money; get per-category monthly breakdowns
Transactions: Query with filters (account, category, payee, month, date range, approval status); get single transactions
Scheduled Transactions: List and retrieve recurring transactions
Money Movements: List budget re-allocations between categories, by month or group
Analysis Tools: Review unapproved transactions grouped by readiness (with anomaly flags like
new_payee,category_drift); find overspent categories
Write Capabilities (opt-in only):
Create: Accounts, categories, category groups, payees, transactions (including bulk and split), and scheduled transactions
Update: Categories, payees, transactions, and scheduled transactions
Batch Operations: Bulk-approve transactions by filter, update multiple transactions at once, reassign transactions between payees
Delete: Transactions and scheduled transactions (requires explicit confirmation)
Import: Trigger imports from linked bank accounts
Key design features: smart default budget resolution, delta/incremental update support, case-insensitive partial name search, and secure API access via Personal Access Token (with optional 1Password integration).
Allows using 1Password CLI reference for token fallback to securely retrieve YNAB API token.
Click on "Install 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 install it from this repo as a standalone Claude Code, Codex, Hermes, or Antigravity plugin, or register the npm package directly and let your MCP client launch it on demand. 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
Install the standalone marketplace from this repository:
/plugin marketplace add oliverames/ynab-mcp-server
/plugin install ynab-mcp-server@ynab-mcp-serverInstall the same marketplace in Codex:
codex plugin marketplace add oliverames/ynab-mcp-server
codex plugin add ynab-mcp-server@ynab-mcp-serverThe 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 |
|
|
|
Codex |
|
|
|
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" |
|
"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.85 coverage with 58 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.Structured contracts for app clients - every tool exposes a human-readable title, an input schema even when it takes no arguments, an output schema, and matching
structuredContent. 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.
Fuzzy search -
search_categoriesandsearch_payeesdo case-insensitive partial matching across all entries. 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 |
| 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 optional goal) |
| 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 ( |
| Get a single transaction by ID (includes subtransactions). Auto-handles composite scheduled-transaction IDs like |
| Write tool: create a transaction with optional split (subtransactions must sum to total) |
| Write tool: bulk create multiple transactions in a single API call (supports split transactions) |
| 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. |
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_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
38 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 | Structured result returned by Audit Account Reconciliation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, but the description adds substantial behavior beyond that: the per-mode request behavior ('one API request' without accountId vs. additional listing with accountId), an explicit 'Makes no changes' statement, and a genuinely useful interpretation note explaining that an old last_reconciled_at is not itself a problem if cleared_balance matches the bank. This equips the agent to interpret results, not just call safely.
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 longer than average but every sentence earns its place: purpose and mode behavior are front-loaded, safety and workflow contrast follow, and the interpretation note closes with actionable diagnostic insight. It is logically ordered and dense without being padded, though slightly wordy compared to the tightest possible version.
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 two-mode diagnostic tool with an output schema already present, the description covers everything an agent needs: what the tool produces in each mode, that it makes no changes, when in the workflow to use it, and how to interpret ambiguous results. The reconciliation domain concepts (last-reconciled date, cleared balance, uncleared transactions) are all explained. Nothing critical is left to inference.
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% — both budgetId and accountId already have meaningful descriptions in the schema, so the baseline of 3 applies. The description reinforces the accountId semantics by explaining what 'inspect in detail' produces (uncleared/unapproved transactions since last reconciliation), but adds no fundamentally new parameter-level information 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 opens with a specific verb+resource ('Read-only reconciliation diagnosis') and precisely enumerates the two behavioral modes: account-level summary without accountId, and detailed transaction listing with accountId. It clearly differentiates itself from siblings like get_transactions (raw retrieval), audit_credit_card_payments (a different audit target), and review_unapproved by framing itself as the 'find what needs attention first' diagnosis step.
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 explicit when-to-use guidance ('use this to find what needs attention first') and states what the tool is NOT for ('actual reconciliation... happens in the YNAB UI'), preventing an agent from attempting to perform reconciliation through this tool. It does not name a specific sibling alternative, but the timing and workflow context ('compare against the bank statement', 'before actual reconciliation') are clear enough for an agent to route correctly.
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 | Structured result returned by Audit Credit Card Payments. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds valuable context about transient differences ('small transient differences appear while recent transactions are pending/uncleared') and interpretation notes, confirming it is non-destructive and explaining expected timeliness of data.
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 well-structured with a clear first sentence stating the core purpose, followed by explanatory details. It is appropriately sized but could be slightly trimmed (e.g., 'Interpretation note' is slightly verbose). Nonetheless, it is efficient and 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, the description does not need to cover return values. It covers everything else: what the tool does, when to use it, behavioral notes, and interpretation guidance. Complete for a read-only audit 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?
Schema coverage is 100% and the description of the single parameter 'budgetId' in the schema is adequate ('Budget ID (uses default if not provided)'). The tool description does not add further parameter semantics, but given complete schema coverage, a 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 clearly states it is a 'read-only audit' comparing credit card balances to payment category balances. It specifies the verb 'audit', the resource 'credit card payments', and uniquely distinguishes itself from sibling tools like get_account or get_transaction by focusing on the audit/reconciliation of payment categories.
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: 'Makes no changes — fix shortfalls by assigning to the payment category via update_month_category.' This tells the agent when to use this tool (to identify shortfalls) and when not to, and points directly to an alternative tool for remediation.
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 | Structured result returned by Detect Recurring Charges. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior. The description adds valuable behavioral context beyond annotations: grouping logic, supported cadences, estimated annual cost, and concrete limitations such as missing variable-amount bills and payee spelling variations. 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 dense but well-organized: the opening sentence states the core function and mechanism, followed by clear use cases, differentiation from a sibling tool, and specific limitations. Every sentence contributes meaningful 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?
Given the rich annotations, complete parameter schema, and output schema, the description covers all necessary selection and usage context. It explains when to use the tool, what it cannot detect, and how to avoid misinterpretation, making it fully adequate 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?
All three parameters are fully documented in the schema with 100% coverage, so the description does not need to repeat them. The description adds some context about exact-amount grouping and cadence detection but does not substantially extend parameter-specific semantics 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 clearly states the tool detects recurring charges from transaction history using a specific mechanism (grouping outflows by payee and exact amount, matching cadence). It also explicitly distinguishes itself from list_scheduled_transactions, making it easy for an agent to select the right 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 explicit use cases: subscription audits and 'what am I paying for' questions. It also names the alternative list_scheduled_transactions and explains when that tool is insufficient, plus warns against concluding a subscription was cancelled without verifying payee variants.
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) | |
| 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 | Structured result returned by Export Transactions. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Descriptors are already covered by annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false) and the description's 'Read-only' is consistent with them. The description adds genuinely valuable behavioral context beyond annotations: the leading-apostrophe CSV escaping to prevent spreadsheet formula injection, and a warning that large date ranges produce large output. Not exhaustive (no header-row or ordering guarantees), but substantial.
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 long but every sentence carries distinct payload: purpose, column semantics, formula-injection defense, usage routing, and output-size caveat. It is front-loaded with the core purpose. The only redundancy is 'Read-only', which merely repeats the annotations — minor, given the density of genuinely useful 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?
Given the 100%-covered schema, rich annotations, and an output schema, the description fills the important remaining gaps: the CSV format itself, dollar/negative-as-outflow column semantics, and the security-critical escaping behavior. Minor omissions such as header-row presence and exact date formatting are acceptable because the output schema exists and the core calling decision is fully supported.
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 8 parameters including the type enum and the one-year default in sinceDate are already documented structurally. The description only adds the cross-tool context 'same filters as get_transactions, including type', which helps an agent re-use knowledge of the sibling tool but does not enrich individual parameter meaning. 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, resource, and output format: 'Export transactions as CSV text' with the exact column list spelled out (date, amount, payee, category, etc.). It is clearly differentiated from its most similar sibling, get_transactions, by the 'same filters as get_transactions' note plus the JSON-vs-CSV contrast.
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 routing rule: 'Use when the user wants data for a spreadsheet or offline analysis; for programmatic work prefer get_transactions (structured JSON).' It also gives operational guidance to narrow with filters when date ranges are large, leaving no ambiguity about when this tool is the right choice.
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 | Structured result returned by Get Account. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint, idempotentHint, and destructiveHint. Description adds 'Read-only' and 'fresh detail' implying no caching. This adds context 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, front-loaded with purpose, no wasted words. Every sentence is informative and 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 presence of output schema and comprehensive annotations, the description covers all necessary context: what it does, when to use it, and what data it returns. It distinguishes from a key sibling 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?
Input schema has 100% description coverage, so description adds minimal value. It reinforces that accountId is the primary key and mentions default behavior for budgetId, but no significant extra 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?
The description specifies the verb 'Get', the resource 'one account', and lists specific details returned (balances, type, reconciliation timestamp, debt metadata). It clearly distinguishes from sibling list_accounts.
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 this tool ('when you already have the account ID and want fresh detail') and when to prefer an alternative ('list_accounts when comparing several accounts').
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 | Structured result returned by Get Budget. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, which the description does not contradict. The description adds transparency about the delta mechanism and response size limits, providing valuable behavioral context 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 well-structured, front-loading the basic purpose then detailing the delta feature. While verbose, every sentence adds value and the length is justified by the complexity of the dual behavior.
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 existence of an output schema, the description need not explain return values. It covers both modes (summary and delta), warns about size limits, and suggests alternatives, making it complete 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 coverage is 100% and both parameters have descriptions. The description adds significant context to lastKnowledgeOfServer (delta export, full budget export, size warnings) but does not add much to budgetId. Overall, it enhances understanding 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 clearly states it gets a budget summary with specific fields (name, currency format, counts) and explains the delta export behavior. This distinguishes it from sibling tools like get_account or get_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?
The description provides explicit guidance on when to use the delta export (pass lastKnowledgeOfServer), warns about large responses and the 8 MB cap, and recommends dedicated list tools for incremental retrieval. This helps avoid misuse.
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 | Structured result returned by Get Budget Health. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds meaningful behavioral context: it combines month data, account balances, and trailing-3-month summaries; explains the green/yellow/red thresholds; notes defaults are not YNAB rules; and discloses an approximate API cost of 4 requests.
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: what it returns, threshold interpretation, and when to use it. Front-loaded with the core purpose and 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 output schema exists and annotations cover safety, the description fully equips an agent to decide when to call it and what to expect. It also gives cost and usage-position context that structured fields do not.
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 does not add extra semantics for budgetId beyond what the schema already provides, but the schema is sufficient on its own.
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 ('snapshot') and resource ('budget health') and enumerates the exact metrics included. It clearly distinguishes itself from sibling tools by framing itself as a composite overview and 'opening move' rather than a drill-down 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?
Explicitly says to use it as the opening move of a monthly review or 'how am I doing' question, then drill into specific tools. This is clear contextual guidance, though it does not name particular alternatives or when-not conditions.
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 | Structured result returned by Get Budget Settings. |
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 well covered. The description adds useful behavioral context by naming what settings are returned and clarifying that inputs are always canonical (dollars and YYYY-MM-DD), which goes beyond the schema and 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 tight sentences with no redundancy: the first states the resource, the second confirms safety, and the third gives precise usage guidance. Information is front-loaded and 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 full annotation coverage, an output schema present, one optional parameter, and a description that covers both when and when not to use the tool, nothing material is missing 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?
Schema description coverage is 100%, and the schema already documents budgetId as optional with a default. The description adds no additional parameter-specific detail, 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?
States a specific verb and resource ('Get a budget's settings') and names the exact contents: currency format (symbol, decimal digits, placement) and date format. This clearly distinguishes it from sibling tools like get_budget and list_budgets, which address different scopes.
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 when to use it ('when formatting amounts or dates for display') and when not to ('not needed for tool inputs, which always use dollars and YYYY-MM-DD'). This gives the agent actionable routing guidance and prevents unnecessary calls.
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 | Structured result returned by Get Category. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds the context of current-month scope and goal fields. No additional behavioral traits needed given annotation 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?
Two efficient sentences with no wasted words. The description is front-loaded with the action and scope, and every sentence provides value.
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 tool with an output schema and clear annotations, the description covers purpose, usage guidance, and boundary conditions. No gaps remain.
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 does not add further meaning beyond the schema; it only implies the 'current month' context which is not a parameter.
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 it retrieves one category's full detail for the current month, including goal/target fields. It uses a specific verb ('Get') and resource ('category') and distinguishes from the sibling tool 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 states when to use ('for goal inspection') and when not to ('for a past or future month's numbers use get_month_category instead'), providing direct guidance on alternatives.
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 | Structured result returned by Get Income Expense Summary. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. Description adds valuable behavioral details: exclusion of transfers and deleted transactions, handling of credit card payments, and refund treatment, which are beyond what annotations 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?
Description is concise: first sentence states core purpose, then clarifies exclusions and use cases. Every sentence adds value with no wasted words.
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 (include/exclude logic, savings rate calculation), the description is complete. Output schema exists, so return values are covered. No gaps noted.
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 parameters are fully documented. Description adds context about default values (6 months back, today) and date format, supplementing the schema without redundancy.
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?
Clearly states it provides a read-only income vs spending summary by month, computed from transaction history. Distinguishes from siblings by specifying exactly what counts as income and spending.
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: for savings-rate reports, month-end closes, and trend questions. Also explains what is excluded (transfers, deleted transactions) and how refunds work, helping the agent avoid misuse.
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 | Structured result returned by Get Money Movement Groups By Month. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description repeats 'Read-only'. It adds some useful context beyond annotations by explaining the groups are batched budget re-allocations and that the scope is a single month, but it does not disclose additional behaviors such as error cases or default budget 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 extremely concise: two short sentences plus a one-word read-only statement. The key scope information is front-loaded, and every sentence earns its place without 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 the simple two-parameter schema, complete schema descriptions, rich annotations, and presence of an output schema, the description covers what an agent needs to invoke the tool correctly. It also names the sibling relationship, which helps routing.
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 month and budgetId are already documented in the input schema. The description's 'for one month' aligns with the month parameter but adds little beyond what the schema already states. 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' for a month. It also clarifies what these groups are ('batched budget re-allocations') and differentiates this tool from list_money_movement_groups by calling it the 'month-scoped view', so an agent can tell them apart.
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 identifies list_money_movement_groups as the broader sibling and frames this tool as its month-scoped counterpart, which conveys when this tool is appropriate. It does not explicitly state a when-not condition or name other alternatives like get_money_movements_by_month, but the context is clear.
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 | Structured result returned by Get Money Movements By Month. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. Description adds 'Read-only' and relationship to sibling, but does not significantly extend behavioral info 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?
Two sentences, no wasted words, front-loaded with purpose. Highly concise and well-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?
Given simple tool with output schema and rich annotations, description covers purpose, usage context, and relationship to sibling completely. No gaps.
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 3. Description does not add additional meaning to parameters beyond what 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?
Clearly states verb 'Get', resource 'money movements (category-to-category budget re-allocations)', and scoped to 'one month'. Distinguishes from sibling 'list_money_movements' by being month-scoped.
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 usage context: 'month-scoped view of list_money_movements' and 'use during month-end review'. Lacks explicit when-not-to-use but provides clear guidance.
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 | Structured result returned by Get Month. |
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 context about what data is included and that values are in dollars, making the tool's behavior more concrete than the annotations alone.
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, no filler. The first sentence front-loads the core purpose and return contents; the second adds use-case guidance and a pointer to the relevant sibling 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 read-only tool with an output schema, two well-documented parameters, and annotations covering safety and idempotency, the description is complete. Nothing an agent needs to know before calling it 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 input schema covers both parameters (month and budgetId) with clear descriptions, so the schema already does the heavy lifting. The description adds a high-level sense of what the month returns but does not add meaning beyond the schema for individual parameters.
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 one budget month's detail') and enumerates exactly what is returned: month totals plus every category's budgeted/activity/balance and goal fields. It also distinguishes itself from sibling tools like get_month_category and get_overspent_categories by clarifying it returns the full month picture.
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 when to use the tool ('workhorse for monthly reviews and budget-vs-actual questions') and points to a specific alternative for a narrower need ('combine with get_overspent_categories for the negative balances only'). This gives an 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_month_categoryGet Month CategoryARead-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 | Structured result returned by Get Month Category. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool as read-only, idempotent, and non-destructive. The description adds no additional behavioral context beyond the operation's scope, and it does not contradict 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 short sentence that is fully front-loaded and contains no filler. Every word contributes to conveying the tool's purpose.
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 tool with a full output schema and comprehensive annotations, the description is adequate. The optional budgetId default behavior is documented in the schema, so 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 fully documents month, budgetId, and categoryId. The description adds no parameter-level detail beyond what the schema already provides, which matches the baseline.
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 specific resource ('category budget'), and the scope ('for a specific month'). This clearly differentiates it from sibling tools like get_category or get_month, which target different resources.
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 the tool: when a category budget for a specific month is needed. However, it does not explicitly mention alternatives or conditions for choosing this tool over related siblings such as get_category or get_budget.
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 | Structured result returned by Get Overspent Categories. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. Description adds domain context ('silently reducing Ready to Assign') but not further behavioral specifics; output schema handles return shape.
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, no filler; the core action is front-loaded and the use-case 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 simple read-only query with one required parameter, rich annotations, and an output schema, the description supplies the missing decision context. Nothing needed to call it correctly is absent.
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 month and budgetId are already documented in the schema. Description merely says 'given month' and does not add format or default behavior beyond 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?
States a specific action ('Get all categories with a negative balance') and scope ('for a given month'). This clearly distinguishes it from generic category/month listing tools and matches 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?
Explicitly tells the agent when to use it: to find prior-month overspends that are reducing current Ready to Assign. Does not name excluded alternatives, but the use-case framing is strong enough to route selection.
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 | Structured result returned by Get Payee. |
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 bar is lower. The description reinforces read-only behavior and adds that the response includes a deleted flag, plus context on why the tool is useful. It does not cover not-found behavior, but for a simple getter this is a reasonable margin above baseline.
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 filler. The core action and resource are front-loaded, followed immediately by the primary use cases and the alternative. 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 simple get-by-ID tool with an output schema present and annotations covering the safety profile, the description provides purpose, use cases, and routing. Nothing required for correct invocation is missing; not-found behavior is a minor omission for a tool this straightforward.
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%: payeeId is described as 'Payee ID' and budgetId as 'Budget ID (uses default if not provided).' The description only adds that lookup is 'by ID,' which maps to payeeId, but does not materially enrich parameter meaning beyond the schema. 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: 'Get one payee by ID' and enumerates the returned fields (name, transfer_account_id, deleted flag). It also distinguishes itself from search_payees by noting that discovery should use the sibling tool, 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?
It states explicit use cases: 'confirm a payee still exists or resolve its transfer account,' and directly names the alternative for discovery ('for discovery use search_payees'). This gives an agent clear routing criteria without needing to inspect siblings.
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 | Structured result returned by Get Payee Location. |
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 that the ID must come from list_payee_locations, but it does not cover error handling, authentication, or default budget behavior. This is adequate but not rich.
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 redundant clauses. It states the purpose, the read-only nature, and the required ID source efficiently.
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 fetch, the annotations, input schema, and output schema cover the essential safety, parameter, and return-value information. The only notable gap is not explicitly distinguishing this from get_payee_locations_by_payee when the caller has a payee ID instead of a payee-location ID.
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 budgetId and payeeLocationId. The description only adds provenance for payeeLocationId by pointing to list_payee_locations, a minor bonus over 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 names a specific verb ('Get'), a singular resource ('one payee location record'), and a clear lookup mechanism ('by its ID'). It also lists the key returned fields (payee, latitude, longitude), which distinguishes it from list_payee_locations and get_payee_locations_by_payee.
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 a clear precondition: the caller needs a payee-location ID from list_payee_locations. It does not explicitly mention sibling alternatives or when not to use this tool, so it stops short of full 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_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 | Structured result returned by Get Payee Locations By Payee. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. The description reinforces 'read-only' and adds the important behavioral detail that results are empty for payees never used in the mobile app. 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 concise sentences with no extraneous information. The first sentence states the action and read-only nature; the second adds use case and a key behavioral note. Every sentence serves a purpose.
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 lookup tool with an output schema (not shown here), the description covers what it does, when to use it, and a crucial behavioral nuance. No additional context is needed.
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 parameters are fully documented in the input schema. The description does not add extra meaning beyond what the schema provides, hitting the baseline for a well-covered 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 clearly states the action ('Get all recorded GPS locations'), resource ('for one payee'), and a specific use case ('confirm which physical merchant an ambiguous payee refers to'). It distinguishes from sibling tools like list_payee_locations by specifying 'for one payee'.
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 on when to use the tool ('confirm which physical merchant an ambiguous payee refers to') and notes a behavioral outcome ('empty for payees never used in YNAB's mobile app'). It does not explicitly compare to alternatives, but the purpose is well framed.
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 | Structured result returned by Get Scheduled Transaction. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds behavioral context beyond annotations: it confirms read-only operation ('Read-only') and clarifies the ID format restriction. 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 sentences, concisely structured. First sentence defines purpose and returned fields. Second sentence provides critical usage guidance. Every sentence adds value 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?
Given the presence of output schema, the description does not need to explain return values in detail. It fully covers the essential behavioral nuance (ID format restriction) and is complete for this tool's complexity.
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 meaning beyond the schema by listing the returned data (next date, frequency, amount, payee, category) and highlighting the invalid composite ID pattern. This provides context not 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 clearly states 'Get one scheduled (recurring) transaction by ID' and lists specific fields returned (next date, frequency, amount, payee, category). It distinguishes from the sibling tool 'get_transaction' by noting that composite realized-transaction IDs are not valid here.
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 the tool (composite IDs with date suffix) and directs users to use 'get_transaction' instead for those cases. Provides clear context for correct invocation.
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. 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 | Structured result returned by Get Transaction. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds significant behavioral detail beyond annotations: composite ID auto-stripping, fallback to scheduled transaction on deletion, and strict 404 for non-composite IDs. No contradictions.
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 paragraph, well-structured, front-loaded with main purpose followed by edge cases. No wasted words.
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?
Covers all relevant behaviors: composite IDs, fallback return shape, strict mode. Output schema exists, so return value details are handled. Complete for a single-fetch 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?
Schema has 100% coverage, so baseline is 3. Description adds value by explaining composite ID handling for transactionId, which is semantic beyond 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 clearly states it gets a single transaction by ID, with specific handling for composite IDs. It distinguishes from sibling tools like get_scheduled_transaction and get_transactions.
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 context for when to use (single transaction retrieval). Implicitly contrasts with get_transactions for multiple. Lacks explicit when-not-to-use statements but covers composite ID edge case.
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
Get transactions with optional filters. Use type='unapproved' or type='uncategorized' to filter. Optionally filter by account, category, payee, or month. You may combine one of accountId/categoryId/payeeId with month to fetch that resource's transactions for a specific month. Each returned transaction includes 'import_payee_name_original' — the raw merchant string from the bank import (e.g. 'AplPay LS ONION RIVEMONTPELIER VT') — which encodes processor flag, merchant name (often longer than the cleaned payee_name), and city+state. This is the primary disambiguation field when payee_name is truncated or ambiguous. YNAB now defaults omitted sinceDate to one year ago; pass an explicit older sinceDate to retrieve older history. Note: large date ranges (6+ months on a busy budget) can return 50KB+ of data; narrow with categoryId/payeeId/month/sinceDate/untilDate filters when possible.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by approval/categorization status | |
| month | No | Filter by month (YYYY-MM-DD, first of month) | |
| 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 }. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Structured result returned by Get Transactions. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive behavior. The description adds value by disclosing default sinceDate behavior, data size warnings, and the inclusion of 'import_payee_name_original' field with its raw merchant string details, providing behavioral context 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 a single, dense paragraph that front-loads the main purpose and filters. Each sentence adds value without redundancy, but it could benefit from slight restructuring for readability. It is appropriately sized for the 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 tool's complexity (9 parameters, optional filters, filter combinations) and the existence of an output schema, the description is comprehensive. It covers filter strategies, default behavior, data volume warnings, and a critical field explanation, making it complete enough for effective tool usage.
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 baseline is 3. The description adds extra meaning by explaining filter combinations and default behaviors, such as the one-year default for sinceDate, and highlights the significance of a parameter field ('import_payee_name_original') not detailed in schema, enhancing semantic 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 'Get transactions with optional filters', specifying the resource (transactions) and action (get). It provides distinct filter types and a key field ('import_payee_name_original'), differentiating it effectively from singular get_transaction and list tools among 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?
The description gives clear guidance on filter combinations (e.g., combining accountId with month) and warns about large date ranges, but does not explicitly mention when to use alternative tools like get_transaction or search tools. It has clear context but lacks exclusions.
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 | Structured result returned by Get User. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false. Description adds that it is read-only and takes no input, and that it returns the user ID. No contradictions.
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 result. Every sentence adds value: first describes action and return, second provides usage guidance.
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 no parameters and presence of output schema, description fully covers purpose, return value, use case, and alternatives. No gaps.
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, baseline is 4. Description correctly states 'takes no input', leaving no ambiguity.
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 the verb 'Get' and resource 'authenticated YNAB user (their user ID)'. Distinguishes from sibling 'ynab_auth_status' by clarifying that this tool returns user ID and verifies the API token, while the sibling is for diagnostics.
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 (verify API token works) and when not to (prefer ynab_auth_status for credential/config diagnostics). Also notes it takes no input, which simplifies usage.
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 | Structured result returned by List Accounts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotency, and non-destructiveness, so the description's 'Read-only' adds minimal new information. However, it adds useful behavioral context beyond annotations: the tool includes closed accounts, returns direct_import_in_error, and requires filtering if only active accounts are wanted. This helps the agent set expectations correctly.
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: the core action and result come first, followed by practical use cases and filtering guidance. Every sentence adds value and there is no redundant filler or restating of the tool name.
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 a low-complexity list operation with an output schema, full parameter documentation, and annotations covering safety. The description adds the missing domain context: what the list contains, why you would use it, and how to handle closed accounts. Nothing critical is missing 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?
Schema description coverage is 100%, so both parameters (budgetId and lastKnowledgeOfServer) are fully documented in the schema. The description does not add parameter-level detail beyond that, which is acceptable given the high coverage. It mentions 'budget' contextually but does not explain the delta-request behavior; the schema already does.
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') and identifies the resource ('all accounts in a budget'), then enumerates the returned fields (balances, type, status, last-reconciled, debt metadata). It clearly distinguishes itself from single-account or other list tools by emphasizing 'all accounts' and account-ID lookup for transaction 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?
The description states explicit use cases: finding account IDs for transaction tools, checking balances, and spotting direct-import errors. It also gives filtering guidance for closed accounts. It does not explicitly name get_account as the alternative for single-account lookups, so it misses a small opportunity to clarify when not to use this tool.
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 | Structured result returned by List Budgets. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description's 'List all budgets' is consistent. However, the description adds no further behavioral context beyond the annotations, and the misleading parameter reference slightly detracts.
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 has two sentences; the first is concise and relevant, the second is confusing and unnecessary. It could be more focused on the actual parameter.
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 simple tool with one optional boolean parameter and an output schema, the description partially explains the tool's purpose but fails to mention the includeAccounts parameter. The misleading reference to budgetId reduces completeness.
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% (1 parameter described), but the description does not explain the includeAccounts parameter. Instead, it introduces a non-existent budgetId parameter, which misleads about the tool's input requirements.
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 'List all budgets' which is a specific verb and resource. However, it also mentions 'omit budgetId to use the last-used budget' despite budgetId not being a parameter in the schema. This introduces confusion and reduces clarity.
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 attempts to guide usage by suggesting to use a budget ID from results, but the reference to 'omit budgetId' is misleading because budgetId is not a parameter. No explicit when-not-to-use or alternatives 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 and deleted items are included with flags — filter on 'hidden'/'deleted' 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 | Structured result returned by List Categories. |
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 detail beyond annotations: the return includes hidden and deleted items flagged for filtering, amounts are in dollars, and the data is scoped to the current month. This gives the agent context about what to expect without relying solely on schema.
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: main purpose first, then usage guidance, then an important data-quality caveat about hidden/deleted items. Every sentence contributes new information, with no filler or repetition of schema details.
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 simple two-parameter schema, rich annotations, and the presence of an output schema, the description covers what an agent needs: scope, purpose, alternatives, and how to handle hidden/deleted entries. There are no obvious missing prerequisites, side effects, or return-behavior gaps that would prevent 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%, and both parameters (budgetId and lastKnowledgeOfServer) already have meaningful descriptions. The tool description does not add extra parameter-level semantics, which is acceptable because the schema carries the load. 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 action (list) and resource (all category groups and categories), plus the output scope (budgeted/activity/balance amounts for the current month). It also distinguishes itself from related tools like get_month and search_categories, making the tool's role immediately clear.
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 when to use this tool: to find category IDs and survey the budget structure. It also names alternatives for adjacent use cases: get_month for a specific month's numbers and search_categories for name-based lookup. The hidden/deleted filtering instruction adds practical guidance for presenting results.
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 | Structured result returned by List Money Movement Groups. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. Description adds useful context about the grouping behavior and how to join with list_money_movements, which is beyond annotation 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?
Two sentences, no wasted words. Purpose and key usage hint 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?
Output schema exists, so return values are covered. Description explains purpose and data relationship. Could be improved with explicit when-to-use/not-to-use compared to sibling list tools.
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. Description does not add any additional information about the budgetId parameter beyond 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 clearly states verb 'List', resource 'money movement groups', and provides context ('batches of related money movements applied together'). It also differentiates from sibling tools by mentioning the join to list_money_movements.
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 guidance: 'Read-only' and suggests using results with list_money_movements. However, no explicit when-not-to-use or alternatives beyond the join hint.
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 | Structured result returned by List Money Movements. |
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 that: the result can be long on old budgets, and the tool returns budget moves rather than transactions. This helps the agent anticipate response size and semantic meaning.
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 deliver purpose, semantic clarification, use case, and a routing recommendation to a sibling tool. There is no filler, and the most important definition 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?
Given the tool's simple shape (one optional parameter, rich annotations, output schema present), the description covers everything needed to select and invoke it correctly. It explains what it returns, when to use it, and when to prefer an alternative, so no critical 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%: the single optional budgetId parameter is documented with 'Budget ID (uses default if not provided)'. The description does not add parameter-level detail, but with complete schema coverage 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 clearly states the action ('List all money movements') and defines the resource as the history of budget re-allocations, including who, how much, from where, to where, and when. It explicitly distinguishes money movements from transactions and names the sibling tool get_money_movements_by_month, making 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 gives an explicit use case ('why did this category's assigned amount change'), explicitly excludes transactions, and recommends a specific alternative (get_money_movements_by_month) when a specific month is needed. This is exactly the kind of when-to-use and when-not-to-use guidance an agent needs.
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 | Structured result returned by List Months. |
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 context by stating it is 'Read-only' and describing the returned summary numbers. While it doesn't mention potential limitations like pagination, the added context is sufficient given 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 concise, consisting of two sentences with no unnecessary words. It front-loads the primary purpose and then provides usage guidance. Every sentence serves a clear purpose.
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, an output schema exists (so return values are documented), and the description covers usage, purpose, and alternatives. The description is complete for the agent to understand when and how to use this tool effectively.
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. The description does not add new information about the parameters beyond what is in the schema. It implicitly relies on the schema to define the two optional parameters.
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: 'List all budget months with summary numbers per month' and specifies the fields returned. It also distinguishes from the sibling 'get_month' tool by mentioning that for per-category detail, one should use 'get_month'.
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 when to use this tool ('use to find which months exist and their headline totals') and when not ('for per-category detail in one month use get_month'). It provides a clear alternative, which helps the agent decide correctly.
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 | Structured result returned by List Payee Locations. |
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 that it lists GPS coordinates recorded at transaction time and that only payees with mobile-recorded transactions appear, which is useful behavioral context 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?
Three sentences, all valuable and front-loaded with the core purpose. No unnecessary words, and the structure is clear.
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 comprehensive annotations, the description sufficiently covers the tool's behavior, constraints (only payees with mobile records), and relationship to the sibling tool. It is complete for its complexity.
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 parameter description in the schema already states 'Budget ID (uses default if not provided).' The tool description does not add any information about the parameter beyond what the schema provides, so it meets the baseline but does not exceed 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 explicitly states it lists all payee locations (GPS coordinates), and distinguishes from the sibling tool get_payee_locations_by_payee by noting the scope difference. Verb 'list' + resource 'payee locations' is specific.
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: 'List all payee locations' and points to the sibling tool for scoped queries. It also notes that only payees with mobile-recorded transactions appear and many budgets have none, which helps set expectations. However, it does not explicitly list when-not-to-use.
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 | Structured result returned by List Payees. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-destructive behavior. Description adds transfer payee nuance and declares read-only, but omits potential pagination or rate limiting.
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 essential information, front-loaded with action and key outcome. No redundant text.
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?
Covers transfer payee usage, alternative search tool, and read-only nature. Could mention output schema or pagination but not necessary given the tool simplicity.
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 already covers both parameters with full descriptions. Description does not add new parameter-level detail beyond what the schema provides, so baseline 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?
Description clearly states 'List all payees with IDs and transfer_account_id' and distinguishes transfer payees. It also contrasts with search_payees, making 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?
Explicitly advises to prefer search_payees for name-based lookup and notes that lists can be long, guiding appropriate usage.
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 | Structured result returned by List Scheduled Transactions. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, destructiveHint=false, and idempotentHint. The description adds important behavioral context: only manually-created entries are returned, not auto-imported ones. No contradictions but no additional details on pagination or rate limits.
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 every word contributes to clarity. 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?
Given the presence of an output schema (as indicated by context signals), the description need not explain return values. It adequately covers the tool's key limitation and offers guidance, making it complete for a list 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?
Schema coverage is 100%, so the description does not need to add param details. It does not provide extra meaning beyond the schema, meeting the baseline.
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 lists scheduled (recurring) transactions and specifies it only includes manually-created entries, distinguishing it from auto-imported charges. This provides a specific verb+resource with a clear 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 explicitly states when to use (manually-created recurring entries) and when not to (auto-imported charges), and suggests using prior-month transaction history as an alternative for auto-imported timing.
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 | Structured result returned by List Undo History. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. Description adds that it reads a local file never the YNAB API, and explains undoable:false entries, providing additional context 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?
Three sentences, no fluff. Front-loaded with main function, then usage and caveats. Every sentence adds value.
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 description fully covers what the tool does, when to use it, and what the entries mean. With output schema present, no need to explain return values.
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 describes the limit parameter well. Description does not add meaning beyond the schema, 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?
The description clearly states it lists the local undo journal of writes, most recent first, with undo capability. It distinguishes from sibling YNAB API tools by specifying it reads a local journal file.
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 to use it before calling undo_operation or to audit writes. It also notes entries with undoable:false are for audit only. No explicit when-not-to, but context makes it clear.
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
Get all unapproved transactions grouped by status: those already categorized (ready to approve) and those still uncategorized (need category first). Each transaction includes a 'flags' array: manually_entered (not bank-imported), match_broken (matched reference is stale — the matched_transaction_id field is read-only via this API; YNAB web/iOS UI is required to clear that link. The transaction itself remains fully mutable: you CAN approve, recategorize, and edit memo via update_transaction. The broken match persists as a cosmetic flag until the user resolves it in the UI.), scheduled_transaction_realized (a realized scheduled entry; its id is composite, uuid_YYYY-MM-DD, and is fully writable — see update_transaction), new_payee (no transaction history for this payee), no_prior_amount_match (novel amount for this payee), category_drift:was_X (payee categorized differently before). GROUP HEADERS: each by_payee group reports category_names (every distinct category in the group) and mixed_categories; category_name is only set when the whole group shares one category and is null when mixed_categories is true — never describe a mixed group by a single category. 'total' is the NET of the group; when its rows run both directions the group also carries mixed_amount_signs:true with inflow_total and outflow_total, so a net that hides refunds is visible as such. Never approve uncategorized transactions without explicit user instruction. For large budgets the full response can exceed 100KB; pass summary:true for counts + by-payee aggregates only, or compact:true to keep per-transaction rows (with IDs) while dropping bulky fields so the response fits inline.
| Name | Required | Description | Default |
|---|---|---|---|
| compact | No | 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. | |
| 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) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes | Structured result returned by Review Unapproved. |
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 — and the description then adds substantial behavioral context: matched_transaction_id is read-only via this API and requires YNAB UI to clear, scheduled entries have composite ids, category_name is null for mixed groups, total is a NET that can hide refunds via mixed_amount_signs, and the safety rule 'Never approve uncategorized transactions without explicit user instruction'. This is exactly the kind of non-obvious runtime behavior an agent needs.
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 purpose and nearly every sentence carries substantive content, so it earns its length. However, the match_broken flag explanation is a single ~90-word nested parenthetical with multiple clauses stacked inside it, and the flag list reads as a dense run-on; the structure would benefit from bullets or split sentences even if the total length stayed the same.
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 description covers every semantic nuance needed to interpret the response correctly: all six flag meanings, group-header invariants (category_name null when mixed, mixed_amount_signs revealing net-hidden refunds), read-only vs mutable fields, the 100KB response-size behavior, and the explicit prohibition on approving uncategorized transactions. An output schema exists, so raw shapes are covered structurally, and what the description adds is the meaning layer — 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 baseline is 3 — the schema already documents compact, summary, and budgetId in detail. The description adds a high-level restatement of the summary/compact trade-off (counts vs per-transaction rows) and ties it to the 100KB overflow behavior, which is modest added value but not enough to push above baseline.
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 opening sentence states a specific verb and resource — 'Get all unapproved transactions grouped by status' — and the ready_to_approve vs needs_category_first split defines a scope that is clearly distinct from the generic get_transactions/get_transaction siblings. The grouping-by-readiness framing makes the tool's unique role unmistakable 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 gives explicit conditional guidance: 'For large budgets the full response can exceed 100KB; pass summary:true... or compact:true' — clear context for when to use each mode. It stops short of an explicit when-not-to-use statement or direct sibling routing (the 'drill into specifics with get_transactions afterwards' pointer lives in the schema, not the description), so it earns a 4 rather than a 5.
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 (case-insensitive, partial match), searching BOTH the category name and its category-group name. Multi-word queries are tokenized and OR-matched, so 'gym fitness membership' matches a category whose name contains any of those words — results are ranked, with whole-phrase and name matches above single-token and group-only matches. Each result reports matched_on ('name' and/or 'group') and matched_terms so a group-only hit is not mistaken for a name hit. Matching ignores HTML entity escaping and collapses runs of whitespace, so 'B&H' and 'B&H' behave the same. Nothing here does synonym expansion: a category named 'GMCF Membership' will not surface for 'gym'. When a search comes back empty or looks wrong, fall back to list_categories (a full dump) before concluding the category does not exist.
| 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 | Structured result returned by Search Categories. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is read-only and idempotent, but the description goes far beyond that: it discloses tokenization, OR-matching, ranking priorities, matched_on fields, HTML entity handling, whitespace collapsing, and explicitly warns about the absence of synonym expansion. This gives the agent a precise model of how results are produced and how to interpret 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 long but every sentence carries operational value: matching rules, ranking, result interpretation, escaping behavior, a negative case, and a fallback instruction. It is front-loaded with the core behavior and closes with actionable 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 search tool with an output schema already present, the description covers everything an agent needs to select and invoke it correctly: what is searched, how matching works, how to interpret results, and what to do when results are questionable. The mention of fallback to list_categories completes the decision loop.
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 query parameter's schema description already includes an example. The tool description adds meaning beyond the schema by explaining tokenization, OR-matching, ranking, and matched_on semantics, which materially improves the agent's understanding of the query parameter and its results.
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'), a resource ('categories'), and the key behavior: case-insensitive partial match against both category name and category-group name. It includes concrete details like tokenized OR-matching and result ranking that clearly distinguish it from the sibling list_categories and get_category 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?
The description explicitly tells the agent when to fall back to list_categories ('When a search comes back empty or looks wrong'), which is clear alternative-selection guidance. It also explains the search semantics so the agent can judge whether the tool fits the current need versus doing a full dump.
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 | Structured result returned by Search Payees. |
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 meaningful behavioral context beyond annotations: case-insensitivity, HTML entity escaping behavior, and single-substring matching. There is no contradiction 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?
Three dense, purposeful sentences. The core behavior is front-loaded, the HTML entity example makes a subtle behavior concrete, and the alternative-tool comparison is placed at the end. Every sentence earns its place with no repetition or 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?
This is a simple read/search tool with strong annotations, a complete input schema, and an output schema present. The description covers the search behavior, provides an example, and gives usage guidance. Nothing material 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?
Schema coverage is 100%, so the baseline is 3. The description nonetheless adds real semantic value to the 'query' parameter by explaining case-insensitivity, HTML entity handling, and substring matching behavior. It does not add anything about budgetId, but the schema already fully documents that parameter.
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: 'Search payees by partial name match (case-insensitive).' It also distinguishes itself from the closest sibling, search_categories, by explaining the matching semantics. This fully clarifies what the tool does and how to tell it apart.
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 compares this tool to search_categories and explains why it is different ('single substring match, not a tokenized OR'). It also gives practical guidance: 'Useful for finding payee IDs' and 'search one distinctive word at a time.' This clearly tells an agent when and how to use it.
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 | Structured result returned by YNAB Auth Status. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, so the description does not need to restate those. It does add useful context about what is being checked (credentials and write-tool enablement), which is more specific than the tool name alone, though it does not describe response details or side effects beyond that.
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?
A single sentence that front-loads the core purpose and states both checks without wasted words. Every word 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 status-check tool with an output schema and safety annotations already provided, the description is complete. An agent can understand what the tool does, what it checks, and that it is safe to invoke.
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, so there is no parameter semantic burden for the description to carry. The baseline of 4 applies because no parameters exist to document and the schema covers everything relevant.
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 ('Check') against a clear resource (YNAB MCP server auth state) and names exactly what is verified: credential configuration and write-tool enablement. This clearly differentiates it from the data-query siblings like get_user or 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 implies the tool is useful for determining whether the server is ready and whether write operations are allowed, but it does not explicitly state when to call it or how it relates to the write-capable siblings like ynab_tool_execute. Usage context is present but only by implication.
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 | Structured result returned by Execute YNAB Tool. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. Description adds context about write tools and the need for YNAB_ALLOW_WRITES=1, which is valuable behavioral information 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?
Two concise sentences with no wasted words. Information is front-loaded: first sentence states core purpose, second adds usage guidance.
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 existence of an output schema (not shown but indicated), the description is complete. It covers how to discover tools, how to call them, and write tool alternatives. The tool is a generic executor, so no need to list siblings.
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 description adds useful guidance: 'Omit or pass an empty object for tools that take no input.' This supplements the schema's description of the input parameter.
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 clearly states the action ('execute'), the resource ('read-only YNAB MCP tool'), and distinguishes from write tools. It also mentions the prerequisite tool ynab_tool_index.
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 advises to use ynab_tool_index first for discovery, and specifies that write tools must use a different pathway (ynab_write_tool_execute). Provides clear 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 | Structured result returned by YNAB Tool Index. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, idempotentHint=true, destructiveHint=false, which align with the description's 'Discover' verb. The description adds value by explaining that the tool lists available tools, going beyond annotation safety profile.
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, front-loaded with the core purpose. Every sentence is informative with no wasted words.
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 index tool with no parameters, the description fully captures purpose and usage context. The existence of an output schema is noted but not required to be described.
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 100% schema description coverage, so no additional meaning is needed. The baseline score of 4 applies as the description correctly omits parameter 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?
The description uses the specific verb 'Discover' and clearly states it is a tool index for YNAB MCP. It lists the capabilities (budgets, accounts, etc.) and distinguishes it from sibling tools that perform specific actions.
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 'Use this when you need YNAB budgets, accounts...' providing clear context for when to invoke. It implies discovery before using specific tools, though it lacks explicit when-not-to-use or alternative guidance.
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. Dates show when Glama detected each change.
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
Each tool targets a distinct resource or action (e.g., get_account vs get_budget, list_payees vs search_payees), with clear read-only roles and no overlapping purposes. The meta-tools ynab_tool_execute and ynab_tool_index are also well-separated.
All tools use snake_case with consistent verb prefixes: get_ for single resources, list_ for collections, search_ for queries, review_ and audit_ for specific views, and ynab_tool_ for meta-tools. No mixing of styles.
23 tools is at the upper end of the 'heavy' range (16-25). While each tool is justified for a complex API like YNAB, the count feels slightly bloated, especially with multiple narrowly scoped list and get tools.
The tool set is heavily read-only, lacking essential write operations like create/update/delete for transactions, categories, and budgets. While it offers thorough inspection capabilities, users cannot modify data, creating significant gaps in a full CRUD lifecycle.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
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.
Personal-finance workspace for AI agents: accounts, spending, budgets, goals, and investments.
Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.
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.12181GPL 3.0
- AlicenseBqualityCmaintenanceExposes YNAB API endpoints as MCP tools, allowing AI assistants to manage budgets, accounts, transactions, and more through natural language.4492MIT
- AlicenseAqualityBmaintenanceConnects AI assistants to YNAB budgets, providing over 30 tools for managing budgets, accounts, transactions, categories, and analytics with delta sync and caching.4733AGPL 3.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/oliverames/ynab-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server