Skip to main content
Glama
calebl

YNAB MCP Server

by calebl

ynab-mcp-server

A Model Context Protocol (MCP) server for interacting with your YNAB plans at https://ynab.com

In order to have an AI interact with this tool, you will need to get your Personal Access Token from YNAB: https://api.ynab.com/#personal-access-tokens. When adding this MCP server to any client, you will need to provide your personal access token as YNAB_API_TOKEN. This token is never directly sent to the LLM. It is stored privately in an environment variable for use with the YNAB api.

A Model Context Protocol server that lets an AI assistant read and modify a YNAB plan.

The server talks to the YNAB API through the official ynab SDK. Your Personal Access Token lives in an environment variable and is never sent to the model.

It runs two ways from one codebase:

  • Local (stdio) — a child process of Claude Code or Claude Desktop on your own machine. Simplest, but only works on that machine while it is running.

  • Remote (Cloudflare Worker) — deployed behind GitHub sign-in and added to claude.ai as a custom connector, so it works from the web and the mobile app with your computer switched off. See DEPLOY.md.

Both entry points register the same tools from src/registry.ts, so a tool written once is available in both.

Other providers:

LightNow

Setup

Get a Personal Access Token from https://api.ynab.com/#personal-access-tokens, then:

npm install
npm run build

Environment variables:

Variable

Required

Purpose

YNAB_API_TOKEN

yes

Personal Access Token used for every API call

YNAB_PLAN_ID

no

Default plan, so tools can omit planId. Find it with ynab_list_plans.

TYPESAFE_API_KEY

no

Operator-owned TypeSafe credential. Required, but not sufficient, to enable category suggestions.

YNAB_AI_CATEGORIZATION

no

Set to "true" together with TYPESAFE_API_KEY to expose the opt-in suggestion tool.

Local: Claude Desktop / Claude Code

{
  "mcpServers": {
    "ynab": {
      "command": "node",
      "args": ["/absolute/path/to/ynab-mcp-server/dist/index.js"],
      "env": {
        "YNAB_API_TOKEN": "your-token",
        "YNAB_PLAN_ID": "your-plan-id"
      }
    }
  }
}

Remote: phone and claude.ai

The stdio server above cannot be reached from a phone. To use these tools from claude.ai or the Claude mobile app, deploy src/worker/ to Cloudflare Workers and add it as a custom connector. DEPLOY.md has the full walk through; the shape of it:

  1. Copy wrangler.example.jsonc to the git-ignored wrangler.jsonc, run npx wrangler login, then create the OAUTH_KV namespace

  2. npm run deploy once to learn your *.workers.dev hostname

  3. Create a GitHub OAuth app whose callback is https://<host>/callback

  4. Use npx wrangler secret put for ALLOWED_GITHUB_LOGIN, YNAB_API_TOKEN, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, and TYPESAFE_API_KEY

  5. Run npm run deploy again

  6. Add https://<host>/mcp as a custom connector in claude.ai

The YNAB token stays a Worker secret and never reaches the client. GitHub sign-in controls who may connect to the remote Worker; the YNAB Personal Access Token controls which YNAB account it reaches. They answer different questions, and neither substitutes for the other. The Worker uses one server-wide YNAB token, so anyone admitted through the GitHub gate reaches the deployer's YNAB account, money, and every plan available to that token—not their own YNAB account. ynab_list_plans lists all of those plans, and a caller-supplied planId overrides the optional YNAB_PLAN_ID default. Any GitHub account other than ALLOWED_GITHUB_LOGIN is refused. This matters because the tool set can create and delete transactions—an unauthenticated endpoint would grant access to those plans to anyone who found the URL.

Related MCP server: ynab-mcp

Why not YNAB OAuth?

YNAB OAuth is deliberately not supported. Its token exchange requires a client secret even with PKCE; an open-source package cannot ship a secret, so a local package cannot honestly implement the authorization-code flow (OAuth application requirements). The only secretless flow YNAB documents is the implicit grant, which expires in two hours with no refresh (OAuth application requirements). YNAB recommends a Personal Access Token for an individual accessing their own account (Personal Access Tokens).

Setting YNAB_READ_ONLY to "true" drops every write tool from the tool list, which is worth considering for a connector you will mostly use on a phone.

Tools

Plan-scoped tools take an optional planId that falls back to YNAB_PLAN_ID. Optional tool inputs may be null; the server treats null the same as omitting that input. All monetary values — in both directions — are plain currency amounts, never YNAB's milliunits; conversion happens in src/tools/money.ts.

Reading

Tool

What it does

ynab_list_plans

Every plan on the account. Run this first to find a plan ID.

ynab_plan_summary

A month at a glance: income, budgeted, activity, Ready to Assign, plus categories split into overspent, underfunded (goal not yet met) and positive_balance. Hidden and deleted categories are excluded.

ynab_list_accounts

Accounts with balances. includeClosedAccounts to see closed ones.

ynab_list_categories

Categories grouped by category group, with goal info.

ynab_list_payees

Payees, for resolving payee IDs.

ynab_list_months

Every plan month with its summary numbers.

ynab_list_scheduled_transactions

Scheduled/recurring transactions.

ynab_get_transactions

Transactions filtered by sinceDate, accountId, categoryId, payeeId, type (all/uncategorized/unapproved) and limit (default 100).

ynab_get_unapproved_transactions

Unapproved transactions, optionally from sinceDate onward.

ynab_suggest_categories

Opt-in, read-only category previews for unapproved, uncategorized ordinary outflows. Deleted and categorized rows are dropped in default mode; approved, reconciled, balance-adjustment, transfer, split, and inflow rows are skipped as applicable.

Category suggestions (optional)

ynab_apply_category_suggestions is a separate write tool that is available without enabling the TypeSafe preview. Provide up to 25 explicit transaction_id, category_id, and expected_content_fingerprint rows. The tool refetches each transaction and rejects stale or ineligible changes; a retry whose category is already applied is a no-op. It supports validation-only dry runs and returns a pre-write undo manifest, but does not perform the undo. It never auto-applies suggestions, calls TypeSafe, or approves transactions.

ynab_suggest_categories is off by default. To expose it, set both an operator-owned TYPESAFE_API_KEY and YNAB_AI_CATEGORIZATION=true, then restart the server. The API key is read from the environment (or a Worker secret), never from a tool argument. Omit transactionIds, pass null, or pass an empty array to fetch unapproved transactions and retain only uncategorized rows; provide IDs to inspect only those transactions. In default mode, the tool checks every retained row for deterministic eligibility and then applies limit to the first eligible outflows in YNAB's returned order. Skipped rows do not consume the limit.

The tool is a dry-run preview: it never writes to YNAB, approves a transaction, or changes the behavior of ynab_update_transaction. It first handles exact facts in code—dropping deleted rows and handling approved or reconciled rows, YNAB balance adjustments, transfers, splits, inflows, existing categories, and hidden/internal categories. In default mode, transactions contains only the eligible rows inspected, transaction_count is that row count, and eligible_transaction_count reports all eligible rows available before the limit. The top-level skipped object reports total_count and a count plus transaction_ids for each reason: skipped_approved, skipped_reconciled, skipped_balance_adjustment, skipped_transfer, skipped_split, skipped_inflow, and skipped_already_categorized. With explicit transactionIds, every non-deleted fetched row remains an individual result, including rows carrying a skipped_* status; deleted rows are omitted. Payee history uses the latest 12 months, capped at 50 qualifying exact-payee rows. The history rule applies only when at least three such rows all use the same still-eligible category; every eligible row without that unanimous signal goes to TypeSafe's pinned jev-1.13.0 System One model in batches of ten. Any disagreement between the history plurality and the model forces needs_review. Every inspected eligible row includes a status, content fingerprint, proposed category, confidence, winning probability, up to three alternatives, and history summary. Applying a suggestion remains a separate, explicit human decision using ynab_apply_category_suggestions (or the general ynab_update_transaction tool).

Enabling this feature sends the transaction's display payee, imported/original payee, memo, amount, date, and account name/type/on-budget status, plus visible category group and category names, to TypeSafe as a third-party processor. It does not send YNAB UUIDs, balances, goals, approval/cleared state, or raw transaction history. TypeSafe's published Jev 1.13 price at the time of this release is $0.042 per million input tokens; output tokens are free. The tool returns preflight estimates, actual token usage, and projected cost on each run and refuses requests over its per-call token/cost ceilings. Pricing and provider limits can change; check https://docs.typesafe.ai/models.

The prototype is intentionally narrow and not default-on. Its supporting 98.3% exact-label, 98.9% top-three, and 60/60 expected-abstention results came from 40 synthetic, single-evaluator fixtures—not a production accuracy claim.

Reporting

Splits are counted through their subtransactions and transfers between your own accounts are excluded, so these report spending rather than money movement.

Tool

What it does

ynab_spending_by_category

Total spend per category over a date range, biggest first, with share of total. Defaults to the last 30 days.

ynab_spending_by_payee

The same, grouped by merchant.

ynab_cash_flow

Income vs spending per month with the running net, from YNAB's own monthly totals. Defaults to the last 6 months.

Writing

Tool

What it does

ynab_create_transaction

Creates a transaction. Needs date, amount, an account (accountId or accountName) and a payee (payeeId or payeeName); category optional as categoryId or categoryName.

ynab_update_transaction

Updates any subset of an existing transaction's fields.

ynab_delete_transaction

Deletes a transaction. Not undoable.

ynab_approve_transaction

Approves (or un-approves) one transaction.

ynab_bulk_approve_transactions

Approves an array of transaction IDs in one API call.

ynab_apply_category_suggestions

Applies up to 25 explicit category suggestions with refetch and stale-data checks, dry-run support, and a pre-write undo manifest. Never auto-applies or approves transactions.

ynab_update_category_budget

Sets the total budgeted amount for a category in a month. Not an increment.

ynab_import_transactions

Triggers an import from linked institutions, the same as hitting Import in the YNAB app.

ynab_move_money

Moves budgeted money between two categories in a month, for covering overspending.

ynab_auto_assign

Spreads Ready to Assign over categories with unmet monthly goals, largest shortfall first. dryRun to preview, maxTotal to cap it.

Names instead of IDs

ynab_create_transaction accepts accountName and categoryName and matches them loosely against the plan, so "ally checking" finds Ally Checking. Closed accounts and hidden categories are never matched. If a name is ambiguous or unrecognised the call fails and names the near misses rather than guessing, and successful calls echo back matchedAccount / matchedCategory so a wrong guess is visible.

Writes that can half-succeed

YNAB has no endpoint for moving money between categories, so ynab_move_money rewrites both categories' budgeted amounts in two calls. It takes from the source first, so a failure in between leaves the money in Ready to Assign rather than double-counted. When that happens the response sets partial: true and carries a recovery line with the original amount to restore. ynab_auto_assign behaves the same way: on failure it reports which categories were already funded and which were left alone.

Tools never throw at the protocol level. Failures come back as an MCP error result (isError: true) with { "success": false, "error": "..." } in the text content, so a failed write is never mistaken for a successful one.

Tool annotations

Every tool advertises MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) alongside its schema. Reading tools are readOnlyHint: true; among the writing tools, only ynab_delete_transaction sets destructiveHint: true. A client may use these hints to decide which calls need a confirmation prompt.

cleared and flagColor

ynab_create_transaction and ynab_update_transaction accept cleared as one of cleared, uncleared, or reconciled, and flagColor as one of red, orange, yellow, green, blue, purple, or "" to clear an existing flag.

Development

npm run watch          # rebuild on change
npm test               # vitest (watch mode)
npm run test:run       # vitest, single run
npm run test:coverage  # coverage report
npm run typecheck      # typecheck both the node and Worker targets
npm run debug          # build, then open the MCP inspector
npm run dev:worker     # run the Worker locally with wrangler
npm run deploy         # deploy the Worker to Cloudflare

dist/ is a build artifact and is not tracked in git; npm run build regenerates it.

Releasing

Bump the version in package.json and update CHANGELOG.md, then merge to main and create a GitHub release tagged in the existing 0.2.0 style (without a v prefix). The workflow stages that release with npm; it does not make the package public. The maintainer must run npm stage list, review it, and run npm stage approve with 2FA to promote it live. Configure a Trusted Publisher on npmjs.com for ynab-mcp-server, pointing at GitHub repository calebl/ynab-mcp-server and the exact workflow filename .github/workflows/publish.yml (the filename must match exactly); under Allowed actions select only npm stage publish.

Adding a tool

Each tool is a self-contained module in src/tools/ exporting name, description, inputSchema (a Zod shape) and execute(input, api). See CLAUDE.md for the full template, then add the module to the tools array in src/registry.ts and write a test in src/tests/. Registering it there serves it from both the stdio server and the Worker; mark writes: true if the tool changes data, which is what YNAB_READ_ONLY filters on.

Useful references:

Contributing

Pull requests targeting main must be raised through no-mistakes. Install it, run no-mistakes init, commit your changes, and push with git push no-mistakes so the review/test pipeline can open a compliant PR. See the no-mistakes quick start for setup.

Compatibility

ynab_list_budgets and ynab_budget_summary remain accepted aliases for the plan-named tools. budgetId and YNAB_BUDGET_ID are deprecated but still accepted; there is no removal date. Use planId and YNAB_PLAN_ID for new integrations.

License

See LICENSE.

Available Tools

23 tools
ynab_approve_transactionApprove TransactionA
Idempotent

Approves an existing transaction in your YNAB plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
approvedNoWhether the transaction should be marked as approved
budgetIdNoDeprecated alias of planId (still accepted)
transactionIdYesThe id of the transaction to approve

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=true), and the description consistently identifies the core operation as approving an existing transaction. It adds little beyond that effect, such as noting that setting 'approved' to false would unapprove, but 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the action and resource with no filler or repetition of the title. Every word earns its place, and the structure is appropriately sized for a simple mutation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-transaction approval tool with strong annotations and fully described parameters, the description provides enough basic context to invoke the tool correctly. It does not mention return values or selection guidance against the bulk-approve sibling, but those are minor gaps given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all 4 parameters with 100% description coverage, including the required transactionId, the default and deprecated alias for planId, and the approved boolean. Since the schema already documents each parameter, the description does not need to compensate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action verb ('Approves') and resource ('existing transaction in your YNAB plan'), making it clear this is an approval mutation rather than a creation, deletion, or listing tool. It does not explicitly name or distinguish the sibling ynab_bulk_approve_transactions, relying on the singular phrasing to signal one-record scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for approving an existing transaction, but it offers no explicit guidance about when not to use it or when to prefer alternatives such as ynab_bulk_approve_transactions or ynab_update_transaction. There are no clear exclusions or conditions beyond the word 'existing'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_auto_assignAuto AssignA

Distributes Ready to Assign across categories whose monthly goal is not yet fully funded, largest shortfall first, until the money runs out. Set dryRun to see the plan without changing anything.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthNoThe plan month in ISO format (e.g. 2024-01-01, must be the first of the month), or 'current'. Defaults to 'current'.
dryRunNoReturn the proposed assignments without writing them (default: false)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
maxTotalNoOnly assign up to this many dollars, even if more is available in Ready to Assign

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a write operation (readOnlyHint=false, idempotentHint=false). The description adds valuable behavioral context: it mutates budget assignments, respects a maxTotal cap, and dryRun prevents changes. It doesn't mention side effects like overwriting existing assignments, but the dryRun disclosure and allocation rule provide solid transparency 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core behavior is front-loaded, and the dryRun safety note is placed second. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write tool with no output schema, the description explains the core behavior, the dryRun preview option, and the stopping condition. It doesn't describe the return value shape, but the absence of an output schema and the presence of dryRun make the behavior sufficiently clear 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.

Parameters3/5

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 all five parameters. The description adds context for dryRun ('see the plan without changing anything') and implies maxTotal's role, but doesn't add meaning beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Distributes'), a clear resource ('Ready to Assign'), and a precise algorithm (largest shortfall first, until money runs out). It distinguishes itself from siblings like ynab_move_money and ynab_update_category_budget by describing an automated allocation behavior rather than a manual transfer or single-category update.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly explains what the tool does and when it applies (categories with monthly goals not fully funded), and mentions dryRun for previewing. It doesn't explicitly name alternative tools or state when not to use it, but the algorithm description makes the use case clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_budget_summaryBudget Summary (legacy)D
Read-only

Former name of ynab_plan_summary.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthNoThe plan month in ISO format (e.g. 2016-12-01). The string 'current' can also be used to specify the current calendar month (UTC)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

D1.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds no behavioral context beyond the legacy alias, which is already reflected in the title 'legacy'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely short, but this is under-specification rather than effective conciseness. A single deprecation note cannot replace a functional tool description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema and annotations provide good invocation details, but the description is missing the core purpose of the tool. An agent cannot reliably decide when to invoke this tool from the given information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter is already documented in the schema. The description contributes nothing extra to parameter understanding, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description only says 'Former name of ynab_plan_summary'; it never states what the tool does. An agent cannot tell from this description that it summarizes a budget, month, or plan.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description names ynab_plan_summary as the current counterpart, which implies this is a legacy alias. However, it does not explicitly say when to use this tool versus its siblings or when to prefer the replacement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_bulk_approve_transactionsBulk Approve TransactionsA
Idempotent

Approves multiple transactions at once. Provide an array of transaction IDs to approve them all in a single API call.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
transactionIdsYesArray of transaction IDs to approve

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile — readOnlyHint=false (mutating), idempotentHint=true, destructiveHint=false — so the bar is lower. The description adds the batch-execution trait ('all in a single API call') but discloses nothing about partial-failure semantics, behavior when some IDs are invalid or already approved, or the response shape. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler. The first fronts the core purpose, the second names the required input and the efficiency benefit ('single API call'). Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a batch mutation, the combination is adequate: annotations cover mutation/idempotency/safety, the schema documents all parameters (including min/max items), and the description covers the batching behavior. The residual gaps — unspecified return value and atomicity on partial failure — are minor for this action and nothing needed 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so planId, budgetId, and transactionIds all already have descriptions in the schema; the baseline of 3 applies. The description's phrase 'array of transaction IDs' merely echoes the schema's own parameter description without adding format detail, limits, or the planId/budgetId relationship.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Approves') and resource ('multiple transactions'), and immediately scopes the action with 'at once' and 'in a single API call,' which implicitly separates it from the singular sibling ynab_approve_transaction. The purpose is unmistakable, though differentiation is implicit rather than explicit (no sibling is named).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The bulk framing ('multiple transactions at once,' 'single API call') tells an agent this is the batched path for approving transactions, so usage is implied. However, there is no explicit when-not-to-use guidance and no named alternative, such as pointing to ynab_approve_transaction for a single ID or noting the 500-item ceiling in prose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_cash_flowCash FlowA
Read-only

Income versus spending, month by month, so you can see whether you are running a surplus. Uses YNAB's own monthly totals rather than re-adding transactions.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthsNoHow many of the most recent months to report on (default: 6)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
sinceDateNoOnly include months on or after this date (ISO format: 2024-01-01). Overrides the months count.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only and non-destructive behavior. The description adds a meaningful detail by saying totals come from YNAB's monthly figures rather than re-adding transactions, but it stops short of describing response format, currency, or any other runtime behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler; the core purpose is front-loaded and the second sentence justifies why the tool exists rather than relying on transaction-level data.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With optional parameters fully documented and safety covered by annotations, the description supplies enough conceptual output detail (month-by-month income, spending, surplus) to invoke the tool confidently. It does not show explicit response shape, but no output schema exists and the tool is simple.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema descriptions cover all four parameters at 100%, so the description does not need to repeat parameter details. It adds no parameter-specific meaning beyond confirming the monthly framing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource as monthly income versus spending and the purpose is to reveal a surplus. It is distinguishable from transaction-listing and category/payee breakdown siblings by its month-level cash-flow framing, though it never names an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'so you can see whether you are running a surplus' gives a concrete use case. It does not enumerate when-not-to-use conditions or point to a specific sibling, but the context is clear enough for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_create_transactionCreate TransactionA

Creates a new transaction in your YNAB plan. The account can be given as accountId or accountName, and the category as categoryId or categoryName - names are fuzzy-matched against the plan. Either payeeId or payeeName must also be provided.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYesThe date of the transaction in ISO format (e.g. 2024-03-24)
memoNoA memo/note for the transaction (optional)
amountYesThe amount in dollars (e.g. -10.99 for money spent, 10.99 for money received)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
clearedNoThe cleared status of the transaction (optional, defaults to uncleared)
payeeIdNoThe id of the payee (optional if payeeName is provided)
approvedNoWhether the transaction is approved (optional, defaults to false)
budgetIdNoDeprecated alias of planId (still accepted)
accountIdNoThe id of the account to create the transaction in (optional if accountName is provided)
flagColorNoThe transaction flag color, or an empty string to clear the flag (optional)
payeeNameNoThe name of the payee (optional if payeeId is provided). YNAB creates the payee if it does not exist.
categoryIdNoThe category id for the transaction (optional)
accountNameNoThe name of the account, matched loosely against your accounts (e.g. 'ally checking'). Optional if accountId is provided.
categoryNameNoThe name of the category, matched loosely against your categories (e.g. 'groceries'). Optional; ignored if categoryId is provided.

TDQS

A4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false (mutation), destructiveHint=false, and openWorldHint=true (fuzzy matching). The description's mention of 'fuzzy-matched' is redundant with openWorldHint. It does not add new behavioral context such as side effects (e.g., payee auto-creation is noted only in schema) or operational requirements. Since the bar is lower with annotations present, but the description contributes minimal additional behavioral insight, a score of 2 reflects the low added value beyond already available structured data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundant words. It front-loads the primary action and then immediately covers the key parameter alternatives and the mandatory payee condition. Every sentence adds critical guidance, and there is zero fluff or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 14 parameters and a thorough schema (100% coverage), the description does not need to enumerate each parameter. It covers the essential decision points: account/category/payee alternatives, the mandatory payee requirement, and the fuzzy matching behavior. The singular 'a new transaction' implies single-record creation, distinguishing it from bulk import. No output schema exists, so return values are not required. The description is complete for the core usage, though it omits edge cases like resolution of ambiguous fuzzy matches.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful value by clarifying the alternative ways to specify account (accountId/accountName) and category (categoryId/categoryName), and by declaring that payeeId or payeeName must be provided – a requirement not present in the schema's required list. This helps the agent understand the mutually exclusive parameter groups and the hidden mandatory field, pushing the score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Creates a new transaction') and the resource ('your YNAB plan'), making the tool's purpose unambiguous. It also highlights the flexibility of using IDs or names for account/category, which distinguishes it from bulk import or update tools. The verb and resource are specific enough to differentiate from siblings like ynab_import_transactions or ynab_update_transaction without needing to inspect schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on how to specify account, category, and payee (via ID or name), and explicitly states that either payeeId or payeeName must be provided – a critical usage constraint not enforced by the schema. However, it does not explicitly contrast with ynab_import_transactions for bulk creation or mention when to avoid using this tool. The guidance is clear for the primary use case but lacks explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_delete_transactionDelete TransactionA
Destructive

Deletes a transaction from the plan. This action cannot be undone.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
transactionIdYesThe ID of the transaction to delete

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotation destructiveHint=true already signals destruction, but the description adds the important context that the action cannot be undone. However, it does not elaborate on downstream effects, such as impact on account balances or related scheduled transactions, so it adds only modest value 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler: the first states the action and target, the second warns about irreversibility. Every word earns its place, and the most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple destructive operation with one required parameter and annotations already declaring destructive/read-only behavior, the description is largely sufficient. It could mention what happens after deletion or what response to expect, but that is not essential for invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 transactionId as the target ID plus planId/budgetId fallback behavior. The description adds no parameter-level meaning beyond what the schema provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Deletes'), a specific resource ('a transaction'), and the scope ('from the plan'). This clearly distinguishes it from sibling tools like ynab_update_transaction or ynab_create_transaction. The purpose is immediately unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to choose this tool over alternatives, nor any conditions or prerequisites for deletion. The agent is left to infer that this is the destructive counterpart to update/create tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_get_transactionsGet TransactionsB
Read-only

Gets transactions from a plan with optional filters. Can filter by date range, account, category, payee, or approval status.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoFilter by transaction type. Defaults to 'all'.
limitNoMaximum number of transactions to return (default: 100)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
payeeIdNoFilter to only transactions with this payee
budgetIdNoDeprecated alias of planId (still accepted)
accountIdNoFilter to only transactions in this account
sinceDateNoOnly return transactions on or after this date (ISO format: 2024-01-01)
categoryIdNoFilter to only transactions in this category

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey read-only and non-destructive behavior. The description adds only the existence of filters, not behavioral details such as default limit behavior, ordering, whether filters combine, or that unapproved transactions require a filter. No contradiction with annotations, but little added transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core action front-loaded. No redundant or promotional language; every sentence contributes to understanding the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter tool with no output schema, the description is thin: it omits default behavior, return shape, and sibling-tool routing. However, the schema covers parameter formats and defaults, and annotations cover the safety profile, so the definition is minimally viable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 summarizes filter categories like date range and account, but does not add meaning beyond the schema's per-parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Gets') and a concrete resource ('transactions from a plan'), then enumerates the supported filter dimensions. It is clearly understandable, but it does not explicitly distinguish itself from sibling tools like ynab_get_unapproved_transactions or ynab_list_scheduled_transactions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is the general transaction-listing tool, but it gives no explicit guidance on when to choose it over alternatives. It does not mention exclusions or point to specialized siblings such as ynab_get_unapproved_transactions for unapproved-only queries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_get_unapproved_transactionsGet Unapproved TransactionsA
Read-only

Gets every unapproved transaction in a plan, optionally limited to those on or after a given date.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
sinceDateNoOnly return transactions on or after this date (ISO format: 2024-01-01). Omit to return all unapproved transactions.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds that it returns every unapproved transaction and can be date-scoped, but discloses no further behavior such as pagination or output shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence with the main action and the sole optional modifier, front-loaded and free of filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with a rich schema and safety annotations, the description is sufficiently complete. It omits output details and explicit sibling distinctions, but those are minor given the schema already handles parameter context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema entries already document planId, the deprecated budgetId alias, the ISO date pattern, and default behavior. The description adds no parameter meaning beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: 'Gets every unapproved transaction in a plan', which immediately separates it from sibling ynab_get_transactions by the 'unapproved' qualifier. It also states the optional date filter without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is clear: this tool is for unapproved transactions, optionally filtered by date, which is a concrete context. It does not explicitly say 'use ynab_get_transactions for all/approved transactions', so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_import_transactionsImport TransactionsA

Imports available transactions on all linked accounts for the plan. This triggers an import from connected financial institutions (equivalent to clicking 'Import' in the YNAB app).

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as non-read-only and non-idempotent; the description adds that it triggers an import from connected financial institutions, which is useful. However, it does not disclose potential side effects beyond the import (e.g., rate limits, network delays, or whether existing pending transactions are overwritten), so the added transparency is modest.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence front-loads the core action and scope; the second adds a clarifying analogy to the YNAB app. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two optional parameters and no output schema, the description explains the action and scope, but it does not indicate what the caller receives after the import (e.g., transaction details, count, or confirmation status). This is a meaningful gap because the absence of an output schema leaves the agent guessing about the return value.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% description coverage for planId and budgetId, including defaulting and deprecation notes, so the description does not need to compensate. The description adds no parameter-specific semantics, which is appropriate given the schema completeness; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('imports'), a precise resource ('available transactions on all linked accounts for the plan'), and clarifies the action as equivalent to clicking Import in the YNAB app. This clearly separates it from sibling tools like create_transaction, get_transactions, and approve_transaction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used to synchronize external bank data by comparing it to the app's Import button, but it does not explicitly state when to use it versus alternatives or when not to use it. No exclusions or alternative tool names are mentioned, so usage guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_accountsList AccountsA
Read-only

Lists all accounts in a plan. Useful for finding account IDs when creating transactions.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
includeClosedAccountsNoInclude closed accounts in the list (default: false)

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the main safety profile is covered. The description adds that all accounts in a plan are returned and that IDs are the useful output, but it does not disclose pagination, ordering, or closed-account handling beyond the schema's includeClosedAccounts field.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no filler, with the action and resource stated first and the use case added as a second sentence. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with optional parameters, the description plus fully-covered schema and annotations provide everything an agent needs to invoke it correctly. No output schema is available, but the stated use case (account IDs) covers the expected return value.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 planId, budgetId, and includeClosedAccounts. The description itself adds no parameter-level detail, but the baseline of 3 applies because the schema carries the param semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'lists' with a clear resource ('all accounts in a plan'), and immediately states the practical purpose of finding account IDs for creating transactions. This distinguishes it from sibling tools like ynab_list_payees, ynab_list_categories, and ynab_get_transactions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for when to use the tool: before creating transactions to look up account IDs. It does not explicitly name alternative tools or state when not to use it, but the use case is specific enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_budgetsList Budgets (legacy)A
Read-only

Former name of ynab_list_plans.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds no behavioral context beyond the deprecation note. It does not mention what happens when called, return format, or any side effects. The description's only behavioral implication is that the tool is legacy, but it does not elaborate on how it behaves. Given annotations exist, the description adds minimal value here.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, short sentence conveys the essential information (the legacy name and its replacement). It is front-loaded and contains no superfluous words, making it highly concise and structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a legacy alias, the description provides the critical information—the canonical tool to use instead—making it functionally complete for deprecation purposes. However, it omits any description of what the tool actually does, which could be necessary if the agent still needs to invoke it directly. Given its redirect nature, this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema is trivially complete (100% coverage). The description does not need to explain parameters, and it doesn't. Per the baseline for 0 parameters, a score of 4 is appropriate since there is nothing to clarify.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states it is the 'Former name of ynab_list_plans,' which clearly identifies it as a legacy alias and implies its function mirrors that of the replacement. However, it does not explicitly state what the tool does (e.g., 'lists budgets'), leaving the agent to infer behavior from the sibling tool's name. It distinguishes itself from siblings by referencing the canonical tool but lacks a direct statement of purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names the alternative tool (ynab_list_plans) and indicates this is the former name, effectively telling the agent to use the replacement instead. This is clear, actionable guidance on when to use this tool versus its successor, with no ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_categoriesList CategoriesA
Read-only

Lists all categories in a plan, grouped by category group. Useful for finding category IDs when creating transactions or updating budgeted amounts.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, non-destructive nature via readOnlyHint=true and destructiveHint=false. The description adds meaningful behavior: categories are returned in groups and all categories are included. It does not cover edge cases like archived or hidden categories, but the annotation coverage lowers the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core listing behavior is front-loaded, followed by a practical use case. It does not repeat annotations or schema details unnecessarily.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with two optional and fully documented parameters, the description plus annotations are sufficient. The output behavior is described as grouped categories containing IDs, and the safe read-only profile is clear. 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so planId and budgetId are already fully documented including defaults and the deprecation alias. The description does not add parameter-level meaning beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists all categories in a plan, grouped by category group. This specific verb+resource combination distinguishes it from sibling tools like ynab_list_accounts and ynab_list_payees. The mention of finding category IDs makes the exact output purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context: useful for finding category IDs when creating transactions or updating budgeted amounts. It does not explicitly name alternatives or state when not to use the tool, but the scenario-based guidance is clear enough for routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_monthsList MonthsA
Read-only

Lists all plan months. Each month contains summary information about budgeting status.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false), and the description adds that each month contains budgeting-status summary information. It does not mention pagination, ordering, or plan scoping details, but for a straightforward read-only list tool the combination of annotations and description is adequate. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler, front-loading the action ('Lists all plan months') before clarifying the content of each month. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with optional parameters and no output schema, the description provides the essential context: all plan months are returned, each with summary budgeting information. It could mention ordering or pagination, but the schema covers parameter defaults, so the definition is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 planId and budgetId, including the default to YNAB_PLAN_ID and the deprecated alias behavior. The tool description adds no parameter-specific information, but the baseline of 3 applies because the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a specific verb and resource: 'Lists all plan months', making the operation and scope explicit. The second sentence clarifies the return content (budgeting status summaries), which distinguishes this tool from sibling list tools like ynab_list_accounts and ynab_list_plans.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for retrieving plan months and their summary budgeting status, but it does not name alternatives or state when not to use it. However, for a simple list operation, the context is reasonably inferred from the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_payeesList PayeesA
Read-only

Lists all payees in a plan. Useful for finding payee IDs when creating transactions.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, covering safety. The description adds that it lists 'all' payees, which is a useful scope note, but it doesn't disclose any behavioral quirks like pagination or performance. The bar is lower due to annotations, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The core action is front-loaded, and the usage hint is placed second. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with optional parameters and no output schema, the description adequately covers purpose and usage. It implicitly conveys that payee IDs are returned ('useful for finding payee IDs'), but it could be more explicit about the exact return shape. Still, it's largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% description coverage for both parameters (planId and budgetId), and the description adds no additional parameter details. With high schema coverage, the baseline is 3, and no extra value is provided beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists all payees in a plan, which is a specific verb and resource. It also explicitly mentions its utility for finding payee IDs when creating transactions, distinguishing it from sibling tools like ynab_list_accounts or ynab_list_categories.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a concrete usage context: find payee IDs for creating transactions. While it doesn't explicitly mention alternatives or when not to use it, the purpose is clear enough and the sibling set is large but the tool's specific role is obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_plansList PlansA
Read-only

Lists all available plans from YNAB API

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds only that it returns all available plans, which is consistent but does not add meaningful behavioral detail 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no wasted words. It front-loads the action and resource immediately, which is ideal for a simple no-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only list tool, the description is sufficient: it states the output scope ('all available plans') and source. There is no output schema, but the description's phrasing adequately conveys that the result is a list of plans without requiring deeper return-value explanation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema is empty and there is no semantic burden on the description. The baseline of 4 applies because no parameter documentation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Lists') and resource ('all available plans from YNAB API'), clearly identifying the scope. It is distinguishable from siblings like ynab_plan_summary because it explicitly says 'lists all available plans' rather than summarizing a single plan.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus alternatives such as ynab_plan_summary. The description merely states what the tool does, leaving the agent to infer selection criteria without any exclusions or comparisons.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_list_scheduled_transactionsList Scheduled TransactionsA
Read-only

Lists all scheduled (recurring) transactions in a plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds modest behavioral detail by saying 'all' scheduled transactions are returned, but it does not go beyond what the name and annotations already suggest, such as absence of filtering or pagination behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler. Every word earns its place: 'Lists' states the action, 'scheduled (recurring)' defines the resource type, and 'in a plan' gives the scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation, the description combined with the annotations and fully documented schema is almost sufficient. It is slightly incomplete because there is no output schema and the description does not note what fields the returned scheduled transactions will contain, but the tool name and simple nature make the return value predictable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 planId and budgetId, including the default and deprecation alias. The description adds no parameter-specific meaning, which fits the baseline of 3 when the schema carries the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Lists') with a clear resource ('scheduled (recurring) transactions') and a scope ('in a plan'). The parenthetical '(recurring)' disambiguates this from regular or unapproved transaction listing siblings, so an agent can distinguish it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'scheduled (recurring)' implies this is the tool for recurring/scheduled transactions, but it does not explicitly state when to use it instead of ynab_get_transactions or ynab_get_unapproved_transactions, nor does it mention any exclusions. Usage context is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_move_moneyMove MoneyA

Moves budgeted money from one category to another in a given month, typically to cover overspending. YNAB has no single move endpoint, so this reads both categories and rewrites their budgeted amounts; if the second write fails the response says exactly which half was applied.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthNoThe plan month in ISO format (e.g. 2024-01-01, must be the first of the month), or 'current'. Defaults to 'current'.
amountYesThe amount to move in dollars (e.g. 25.00). Must be positive.
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
toCategoryIdYesThe ID of the category to give money to
fromCategoryIdYesThe ID of the category to take money from

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by disclosing the non-atomic implementation: it reads both categories, rewrites both budgeted amounts, and explains the partial-failure response. This is exactly the kind of behavioral detail an agent needs and that annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first states the core action and typical use; the second adds only high-value implementation and failure-mode details. There is no filler, repetition, or unnecessary background.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with six fully documented parameters, the description provides the missing behavioral context: non-atomicity, partial-failure reporting, and the cover-overspending purpose. The only omitted detail is the exact success return shape, but the description's failure-mode disclosure compensates and no output schema is defined.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 month format/default, positive amount, plan/budget IDs, and category IDs. The description adds no new parameter-level semantics beyond restating the transfer direction, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and direct object: 'Moves budgeted money from one category to another in a given month.' It also clarifies the motivating use case, covering overspending, and distinguishes itself from a plain category budget update by noting there is no single YNAB move endpoint.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Typically to cover overspending' gives a concrete triggering context, and the move-vs-set semantics imply when this tool is appropriate rather than a simple budget update. It does not explicitly name alternatives or exclusions, but the intended usage is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_plan_summaryPlan SummaryA
Read-only

Get a summary of the plan for a specific month highlighting overspent categories that need attention and categories with a positive balance that are doing well.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthNoThe plan month in ISO format (e.g. 2016-12-01). The string 'current' can also be used to specify the current calendar month (UTC)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)

TDQS

A3.6/5.0
Behavior3/5

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 context about the month scoping and the category-level highlight focus, but it does not disclose more operational details like response structure or any limitations. No contradictions 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single concise sentence communicates the operation, scope, and key output signals with no redundant wording. All content earns its place and the main purpose is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 three optional parameters already fully documented in the schema, the description adequately explains what the summary highlights. The lack of an output schema is partially compensated by the description's mention of overspent and positive-balance categories, though exact return fields are not specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides full 100% coverage of all three optional parameters with detailed descriptions and defaults. The tool description adds no parameter-specific meaning, so the schema carries the burden and the baseline score applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves a month-specific plan summary and specifies the key outputs (overspent categories and positive-balance categories). It is distinct from obvious siblings like ynab_budget_summary by focusing on plan month and category health, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it—when a month-level plan summary is needed with attention/positive category highlights. It provides no explicit guidance on when not to use it or which sibling tool might be more appropriate for other summary needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_spending_by_categorySpending By CategoryA
Read-only

Totals spending per category over a date range, biggest spend first. Splits are counted through their subtransactions, and transfers between your own accounts are excluded.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoOnly return the top N categories by spend
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
sinceDateNoStart of the range, inclusive (ISO format: 2024-01-01). Defaults to 30 days ago.
untilDateNoEnd of the range, inclusive (ISO format: 2024-01-31). Defaults to no end date.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool read-only and non-destructive, and the description adds meaningful behavioral details: split transactions are counted via subtransactions, and transfers between own accounts are excluded. These nuances significantly affect results and are not inferable from annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense, purposeful sentences with no filler. The core behavior and ordering are front-loaded, and the two edge-case clarifications are packed into a single second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential behavior, ordering, split handling, and transfer exclusion, which is enough for an agent to select and invoke the tool correctly. There is no output schema, but the return concept is simple and obvious from the title; explicitly describing response fields would push this to a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema documents all five parameters with full descriptions and defaults, so the description does not need to repeat them. It adds no parameter-specific meaning beyond what the schema already provides, matching the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Totals spending per category over a date range') and ordering ('biggest spend first'), naming the exact resource and operation. It also distinguishes itself from the sibling ynab_spending_by_payee by explicitly focusing on categories rather than payees.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description establishes clear analytical context: this is for category-level spending totals over a date range, which lets an agent separate it from transaction-listing and mutation tools. It does not explicitly name alternatives or say when not to use it, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_spending_by_payeeSpending By PayeeA
Read-only

Totals spending per payee over a date range, biggest spend first - where the money actually goes by merchant. Splits are counted through their subtransactions, and transfers between your own accounts are excluded.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoOnly return the top N payees by spend
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
sinceDateNoStart of the range, inclusive (ISO format: 2024-01-01). Defaults to 30 days ago.
untilDateNoEnd of the range, inclusive (ISO format: 2024-01-31). Defaults to no end date.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context beyond annotations: it explains how splits are handled (counted through subtransactions) and that transfers between own accounts are excluded. This is useful edge-case disclosure that helps an agent predict results. It doesn't mention pagination or output format, but with no output schema and read-only semantics, the key behaviors are covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The core function is front-loaded, and the edge-case behaviors (splits, transfers) are packed into the second sentence. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only aggregation tool with 100% schema coverage and no output schema, the description is nearly complete. It covers the core function, the sort order, the split handling, and the transfer exclusion. The only minor gap is that it doesn't describe the return shape (e.g., whether it returns a list of payee names with amounts), but with no output schema and a clear aggregation description, this is a small gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 all parameters (limit, planId, budgetId, sinceDate, untilDate) with defaults and formats. The description adds the conceptual meaning of 'limit' (top N payees by spend) and the date range concept, but doesn't add much beyond the schema. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Totals spending per payee over a date range, biggest spend first'. It also adds a helpful real-world framing ('where the money actually goes by merchant') and distinguishes it from related tools by mentioning specific exclusions (splits counted via subtransactions, transfers between own accounts excluded). This is a specific verb+resource with clear scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool: when you need spending totals by merchant/payee over a date range. It doesn't explicitly name alternatives or say when not to use it, but the sibling list includes ynab_spending_by_category and ynab_cash_flow, and the description's focus on payees/merchants makes the use case clear. It lacks explicit exclusions or alternative routing, so it doesn't earn a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_update_category_budgetUpdate Category BudgetA
Idempotent

Updates the budgeted amount for a category in a specific month. Use this to allocate funds to categories or move money between categories.

ParametersJSON Schema
NameRequiredDescriptionDefault
monthYesThe plan month in ISO format (e.g. 2024-01-01). Must be the first day of the month.
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
budgetIdNoDeprecated alias of planId (still accepted)
budgetedYesThe amount to budget in dollars (e.g. 500.00). This sets the total budgeted amount, not an increment.
categoryIdYesThe ID of the category to update

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description states that the tool mutates budgeted amounts, which is consistent with readOnlyHint=false and idempotentHint=true and does not contradict the annotations. It adds little beyond the core operation, such as effects on available amounts, permissions, or return behavior, but the annotations already cover the basic 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only two sentences and front-loads the core operation. It is concise and easy to scan, though the second sentence's overlap with ynab_move_money makes it slightly less crisp than it could be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple update operation with fully documented parameters and informative annotations, the description is sufficiently complete for an agent to select and invoke the tool. The main missing element is explicit guidance about when to prefer ynab_move_money, but this is a minor gap given the straightforward purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters are already well documented, including the critical fact that budgeted sets the total amount rather than an increment. The tool description adds no parameter-specific meaning beyond the general allocation/move-money framing, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and object: it updates the budgeted amount for a category in a specific month. It is clear about the core operation, but it does not explicitly distinguish itself from sibling tools like ynab_move_money, and the phrase 'move money between categories' blurs that boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a direct use case: 'Use this to allocate funds to categories or move money between categories.' However, it does not mention alternatives or exclusions, which matters because ynab_move_money exists as a sibling and may be the more appropriate tool for cross-category moves.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ynab_update_transactionUpdate TransactionA
Idempotent

Updates an existing transaction. All fields except transactionId are optional - only provide fields you want to change.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoThe date of the transaction in ISO format (e.g. 2024-03-24)
memoNoA memo/note for the transaction
amountNoThe amount in dollars (e.g. -10.99 for outflow, 10.99 for inflow)
planIdNoThe plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)
clearedNoThe cleared status
payeeIdNoThe ID of the payee
approvedNoWhether the transaction is approved
budgetIdNoDeprecated alias of planId (still accepted)
accountIdNoMove transaction to a different account
flagColorNoThe transaction flag color, or an empty string to clear the flag
payeeNameNoThe name of the payee (creates new payee if doesn't exist)
categoryIdNoThe category ID for the transaction
transactionIdYesThe ID of the transaction to update

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that the operation is non-read-only and non-destructive. The description adds useful behavioral context beyond that: it is a partial update where omitted fields are left unchanged. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two focused sentences with no superfluous content. The core purpose is front-loaded, and the parameter guidance is stated immediately and clearly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the 13 parameters, complete schema descriptions, and annotations covering idempotence and destructive behavior, the description is sufficiently complete. The only minor omission is the return value, but this is not critical for correct invocation of an update tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by clarifying that all non-transactionId fields are optional and that only fields explicitly provided are changed, which prevents an agent from sending the entire object unnecessarily.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Updates') and resource ('an existing transaction'), and the word 'existing' clearly distinguishes it from ynab_create_transaction and ynab_delete_transaction. It is unambiguous about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: use this to modify an existing transaction, and only send fields to change. It does not explicitly name alternatives or state when not to use it, but the partial-update guidance is practical and sufficient for selection.

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.

  1. 22 tool updatesv0.3.0
    • Changedynab_approve_transaction8 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / approved / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "description": "Whether the transaction should be marked as approved",
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / approved / default
        Removed value: -true
      • removedInput schema / properties / approved / type
        Removed value: -"boolean"
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The id of the budget containing the transaction (optional, defaults to the budget set in the YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Addedynab_auto_assign
    • Changedynab_budget_summary10 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget to get a summary for (optional, defaults to the budget set in the YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / month / anyOf
        Added value: +[
        +  {
        +    "default": "current",
        +    "description": "The plan month in ISO format (e.g. 2016-12-01). The string 'current' can also be used to specify the current calendar month (UTC)",
        +    "pattern": "^(current|\\d{4}-\\d{2}-\\d{2})$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / month / default
        Removed value: -"current"
      • changedInput schema / properties / month / description
        Previous value: -"The budget month in ISO format (e.g. 2016-12-01). The string 'current' can also be used to specify the current calendar month (UTC)"New value: +"The plan month in ISO format (e.g. 2016-12-01). The string 'current' can also be used to specify the current calendar month (UTC)"
      • removedInput schema / properties / month / pattern
        Removed value: -"^(current|\\d{4}-\\d{2}-\\d{2})$"
      • removedInput schema / properties / month / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_bulk_approve_transactions7 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
      • addedInput schema / properties / transactionIds / maxItems
        Added value: +500
      • addedInput schema / properties / transactionIds / minItems
        Added value: +1
    • Addedynab_cash_flow
    • Changedynab_create_transaction30 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / accountId / anyOf
        Added value: +[
        +  {
        +    "description": "The id of the account to create the transaction in (optional if accountName is provided)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / accountId / description
        Previous value: -"The id of the account to create the transaction in"New value: +"The id of the account to create the transaction in (optional if accountName is provided)"
      • removedInput schema / properties / accountId / type
        Removed value: -"string"
      • addedInput schema / properties / accountName
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The name of the account, matched loosely against your accounts (e.g. 'ally checking'). Optional if accountId is provided.",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The name of the account, matched loosely against your accounts (e.g. 'ally checking'). Optional if accountId is provided."
        +}
      • changedInput schema / properties / amount / description
        Previous value: -"The amount in dollars (e.g. 10.99)"New value: +"The amount in dollars (e.g. -10.99 for money spent, 10.99 for money received)"
      • addedInput schema / properties / approved / anyOf
        Added value: +[
        +  {
        +    "description": "Whether the transaction is approved (optional, defaults to false)",
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / approved / type
        Removed value: -"boolean"
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The id of the budget to create the transaction in (optional, defaults to the budget set in the YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / categoryId / anyOf
        Added value: +[
        +  {
        +    "description": "The category id for the transaction (optional)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / categoryId / type
        Removed value: -"string"
      • addedInput schema / properties / categoryName
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The name of the category, matched loosely against your categories (e.g. 'groceries'). Optional; ignored if categoryId is provided.",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The name of the category, matched loosely against your categories (e.g. 'groceries'). Optional; ignored if categoryId is provided."
        +}
      • addedInput schema / properties / cleared / anyOf
        Added value: +[
        +  {
        +    "description": "The cleared status of the transaction (optional, defaults to uncleared)",
        +    "enum": [
        +      "cleared",
        +      "uncleared",
        +      "reconciled"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / cleared / description
        Previous value: -"Whether the transaction is cleared (optional, defaults to false)"New value: +"The cleared status of the transaction (optional, defaults to uncleared)"
      • removedInput schema / properties / cleared / type
        Removed value: -"boolean"
      • addedInput schema / properties / date / pattern
        Added value: +"^\\d{4}-\\d{2}-\\d{2}$"
      • addedInput schema / properties / flagColor / anyOf
        Added value: +[
        +  {
        +    "description": "The transaction flag color, or an empty string to clear the flag (optional)",
        +    "enum": [
        +      "red",
        +      "orange",
        +      "yellow",
        +      "green",
        +      "blue",
        +      "purple",
        +      ""
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / flagColor / description
        Previous value: -"The transaction flag color (red, orange, yellow, green, blue, purple) (optional)"New value: +"The transaction flag color, or an empty string to clear the flag (optional)"
      • removedInput schema / properties / flagColor / type
        Removed value: -"string"
      • addedInput schema / properties / memo / anyOf
        Added value: +[
        +  {
        +    "description": "A memo/note for the transaction (optional)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / memo / type
        Removed value: -"string"
      • addedInput schema / properties / payeeId / anyOf
        Added value: +[
        +  {
        +    "description": "The id of the payee (optional if payeeName is provided)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / payeeId / type
        Removed value: -"string"
      • addedInput schema / properties / payeeName / anyOf
        Added value: +[
        +  {
        +    "description": "The name of the payee (optional if payeeId is provided). YNAB creates the payee if it does not exist.",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / payeeName / description
        Previous value: -"The name of the payee (optional if payeeId is provided)"New value: +"The name of the payee (optional if payeeId is provided). YNAB creates the payee if it does not exist."
      • removedInput schema / properties / payeeName / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "accountId",
        -  "date",
        -  "amount"
        -]New value: +[
        +  "date",
        +  "amount"
        +]
    • Changedynab_delete_transaction5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_get_transactions18 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / accountId / anyOf
        Added value: +[
        +  {
        +    "description": "Filter to only transactions in this account",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / accountId / type
        Removed value: -"string"
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / categoryId / anyOf
        Added value: +[
        +  {
        +    "description": "Filter to only transactions in this category",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / categoryId / type
        Removed value: -"string"
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "description": "Maximum number of transactions to return (default: 100)",
        +    "exclusiveMinimum": 0,
        +    "maximum": 1000,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / limit / type
        Removed value: -"number"
      • addedInput schema / properties / payeeId / anyOf
        Added value: +[
        +  {
        +    "description": "Filter to only transactions with this payee",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / payeeId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
      • addedInput schema / properties / sinceDate / anyOf
        Added value: +[
        +  {
        +    "description": "Only return transactions on or after this date (ISO format: 2024-01-01)",
        +    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / sinceDate / type
        Removed value: -"string"
      • addedInput schema / properties / type / anyOf
        Added value: +[
        +  {
        +    "description": "Filter by transaction type. Defaults to 'all'.",
        +    "enum": [
        +      "all",
        +      "uncategorized",
        +      "unapproved"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / type / enum
        Removed value: -[
        -  "all",
        -  "uncategorized",
        -  "unapproved"
        -]
      • removedInput schema / properties / type / type
        Removed value: -"string"
    • Changedynab_get_unapproved_transactions6 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget to fetch transactions for (optional, defaults to the budget set in the YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
      • addedInput schema / properties / sinceDate
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Only return transactions on or after this date (ISO format: 2024-01-01). Omit to return all unapproved transactions.",
        +      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Only return transactions on or after this date (ISO format: 2024-01-01). Omit to return all unapproved transactions."
        +}
    • Changedynab_import_transactions5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_list_accounts7 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / includeClosedAccounts / anyOf
        Added value: +[
        +  {
        +    "description": "Include closed accounts in the list (default: false)",
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / includeClosedAccounts / type
        Removed value: -"boolean"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_list_categories5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_list_months5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_list_payees5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Addedynab_list_plans
    • Changedynab_list_scheduled_transactions5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Addedynab_move_money
    • Addedynab_plan_summary
    • Addedynab_spending_by_category
    • Addedynab_spending_by_payee
    • Changedynab_update_category_budget6 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • changedInput schema / properties / month / description
        Previous value: -"The budget month in ISO format (e.g. 2024-01-01). Must be the first day of the month."New value: +"The plan month in ISO format (e.g. 2024-01-01). Must be the first day of the month."
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
    • Changedynab_update_transaction28 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / accountId / anyOf
        Added value: +[
        +  {
        +    "description": "Move transaction to a different account",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / accountId / type
        Removed value: -"string"
      • addedInput schema / properties / amount / anyOf
        Added value: +[
        +  {
        +    "description": "The amount in dollars (e.g. -10.99 for outflow, 10.99 for inflow)",
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / amount / type
        Removed value: -"number"
      • addedInput schema / properties / approved / anyOf
        Added value: +[
        +  {
        +    "description": "Whether the transaction is approved",
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / approved / type
        Removed value: -"boolean"
      • addedInput schema / properties / budgetId / anyOf
        Added value: +[
        +  {
        +    "description": "Deprecated alias of planId (still accepted)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / budgetId / description
        Previous value: -"The ID of the budget (optional, defaults to YNAB_BUDGET_ID environment variable)"New value: +"Deprecated alias of planId (still accepted)"
      • removedInput schema / properties / budgetId / type
        Removed value: -"string"
      • addedInput schema / properties / categoryId / anyOf
        Added value: +[
        +  {
        +    "description": "The category ID for the transaction",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / categoryId / type
        Removed value: -"string"
      • addedInput schema / properties / cleared / anyOf
        Added value: +[
        +  {
        +    "description": "The cleared status",
        +    "enum": [
        +      "cleared",
        +      "uncleared",
        +      "reconciled"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / cleared / enum
        Removed value: -[
        -  "cleared",
        -  "uncleared",
        -  "reconciled"
        -]
      • removedInput schema / properties / cleared / type
        Removed value: -"string"
      • addedInput schema / properties / date / anyOf
        Added value: +[
        +  {
        +    "description": "The date of the transaction in ISO format (e.g. 2024-03-24)",
        +    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / date / type
        Removed value: -"string"
      • addedInput schema / properties / flagColor / anyOf
        Added value: +[
        +  {
        +    "description": "The transaction flag color, or an empty string to clear the flag",
        +    "enum": [
        +      "red",
        +      "orange",
        +      "yellow",
        +      "green",
        +      "blue",
        +      "purple",
        +      ""
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / flagColor / description
        Previous value: -"The transaction flag color"New value: +"The transaction flag color, or an empty string to clear the flag"
      • removedInput schema / properties / flagColor / enum
        Removed value: -[
        -  "red",
        -  "orange",
        -  "yellow",
        -  "green",
        -  "blue",
        -  "purple"
        -]
      • removedInput schema / properties / flagColor / type
        Removed value: -"string"
      • addedInput schema / properties / memo / anyOf
        Added value: +[
        +  {
        +    "description": "A memo/note for the transaction",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / memo / type
        Removed value: -"string"
      • addedInput schema / properties / payeeId / anyOf
        Added value: +[
        +  {
        +    "description": "The ID of the payee",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / payeeId / type
        Removed value: -"string"
      • addedInput schema / properties / payeeName / anyOf
        Added value: +[
        +  {
        +    "description": "The name of the payee (creates new payee if doesn't exist)",
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / payeeName / type
        Removed value: -"string"
      • addedInput schema / properties / planId
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The plan ID (optional, defaults to YNAB_PLAN_ID; budgetId is a deprecated alias)"
        +}
  2. 17 tool updatesv1.0.0
    • Removedlist_budgets
    • Addedynab_approve_transaction
    • Addedynab_budget_summary
    • Addedynab_bulk_approve_transactions
    • Addedynab_create_transaction
    • Addedynab_delete_transaction
    • Addedynab_get_transactions
    • Addedynab_get_unapproved_transactions
    • Addedynab_import_transactions
    • Addedynab_list_accounts
    • Addedynab_list_budgets
    • Addedynab_list_categories
    • Addedynab_list_months
    • Addedynab_list_payees
    • Addedynab_list_scheduled_transactions
    • Addedynab_update_category_budget
    • Addedynab_update_transaction
  3. 1 tool update
    • First observedlist_budgets

TDQS

B3.1/5.0

Scored across 23 tools

Disambiguation3/5

Most tools target distinct resources, but there is real overlap: ynab_list_budgets duplicates ynab_list_plans, ynab_budget_summary duplicates ynab_plan_summary, and ynab_get_unapproved_transactions overlaps with ynab_get_transactions. The approval tools also have single and bulk variants that could be conflated, though the descriptions help.

Naming Consistency4/5

Tool names consistently use the ynab_ prefix and mostly follow a verb_noun pattern like ynab_list_accounts and ynab_create_transaction. The mix of list/get and the plan/budget terminology shift is slightly inconsistent, but the overall convention is predictable.

Tool Count3/5

23 tools is at the high end and includes duplicate legacy aliases that inflate the count. The core operations are broad enough to justify many tools, but the surface feels heavier than necessary for a focused budgeting server.

Completeness4/5

Transactions, approvals, categories, budgets, payees, accounts, and reporting are well covered, and the create/read/update/delete lifecycle for transactions is complete. Notable gaps remain for scheduled transactions, which can only be listed, and for managing categories/payees themselves.

Maintenance

ActivityMaintained
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    An MCP server that allows users to interact with YNAB data, enabling access to account balances, transactions, and the creation of new transactions through the Model Context Protocol.
    8
    6
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server for interacting with YNAB (You Need A Budget). Provides tools for accessing budget data through MCP-enabled clients like Claude Desktop.
    4
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol server that enables interaction with You Need A Budget (YNAB) via their API, allowing users to manage budgets, accounts, categories, and transactions through natural language.
    2
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A Model Context Protocol server for YNAB (You Need A Budget). Enables users to query budgets, accounts, categories, transactions, and more, as well as create, update, and delete transactions and manage scheduled transactions from any MCP client.
    27
    2
    MIT