Skip to main content
Glama
RealBeepMcJeep

ynab-mcp-lite

ynab-mcp-lite

A deliberately tiny, non-destructive MCP server for YNAB, built on the official public API. Read-first: the only write it can ever perform is adding transactions — always unapproved, so nothing affects a budget until the account owner reviews and approves it in the YNAB app.

Why another YNAB MCP server?

Several exist. Most are stdio-first, and their safety is configuration — one env flag away from full read-write against a budget. This one makes the dangerous operations impossible by construction:

  • Only GET requests and "create transaction(s)" POSTs exist in the codebase. There is no code path for update, delete, approve, import-trigger, or any budget/category mutation — and a CI guard (part of the test suite) fails the build if a destructive call ever appears in the source.

  • Created transactions are forced unapproved; the server cannot approve anything. Worst-case recovery for a wrong entry is deleting an unapproved item with two taps in the app.

  • Every write tool is dry-run by default — preview first, explicit dry_run=false after that.

  • A duplicate pre-check refuses to add an amount that already exists in the same account within ±N days, unless explicitly overridden.

  • Stateless. No storage, no cache. The token comes from the environment and is never logged or returned by any tool.

Related MCP server: YNAB MCP Server

Tools

Reads (always available)

tool

description

auth_status

token validity, plan list, server config

list_plans

plans (budgets) on the account

list_accounts

accounts: id, name, type, on-budget, balance

list_categories

categories + groups, budgeted/activity/balance

list_payees

payees, optional name search

get_transactions

transactions, filter by account / dates / unapproved

Add-only writes (registered only when YNAB_ALLOW_WRITES=1)

tool

description

create_transaction

add one transaction (dry-run default)

create_transactions

add up to 50 in one call

Names (account, payee, category) resolve loosely: exact id, exact name, or a unique substring — ambiguity is an error listing the candidates, never a guess. Amounts are in dollars (e.g. -12.34) and converted to YNAB milliunits with exact decimal math. Payee names that don't exist yet are passed through so YNAB can create them.

Status

  • Server + 45-test suite green (no network: a fake YNAB over httpx.MockTransport)

  • Container build, GHCR publish and Dockge deploy kit included (deploy/)

  • Writes ship disabled; enable with YNAB_ALLOW_WRITES=1 on a single-user deploy

Quick start

Docker

docker run --rm -p 8000:8000 \
  -e YNAB_API_TOKEN="<your token>" \
  ghcr.io/realbeepmcjeep/ynab-mcp-lite:latest

MCP endpoint: http://localhost:8000/mcp · health: /healthz.

From source

uv sync
YNAB_API_TOKEN=<token> uv run ynab-mcp-lite serve                  # HTTP (127.0.0.1:8000)
YNAB_API_TOKEN=<token> uv run ynab-mcp-lite serve --transport stdio

Use with an MCP client

HTTP clients: point at http://<host>:8000/mcp. For stdio clients:

{
  "mcpServers": {
    "ynab": {
      "command": "ynab-mcp-lite",
      "args": ["serve", "--transport", "stdio"],
      "env": { "YNAB_API_TOKEN": "<your token>" }
    }
  }
}

Configuration

All via environment; every variable except the token is optional.

variable

default

meaning

YNAB_API_TOKEN

YNAB Personal Access Token (Settings → Developer)

YNAB_ALLOW_WRITES

0

1 = register the add-only write tools

YNAB_PLAN_ID

default plan id; a single plan resolves automatically

YNAB_DEDUPE_DAYS

10

duplicate pre-check window, in days

YNAB_ALLOWED_HOSTS

container name + localhost

Host allowlist for the HTTP transport

YNAB_BASE_URL

https://api.ynab.com/v1

API base (development only)

YNAB_MCP_HOST / YNAB_MCP_PORT

127.0.0.1 / 8000

bind address for serve

Reconciliation workflow

The reason the write path exists: reconciling a card or account against a statement / receipt screenshots.

  1. Pull what's already recorded: get_transactions for the account and date range.

  2. Diff against the statement (anywhere: chat, script, human).

  3. Preview the additions with create_transaction(s) (dry-run default).

  4. Create them for real (dry_run=false) — all unapproved, optionally flagged for easy review.

  5. Approve them in the YNAB app when satisfied; the duplicate pre-check makes overlapping or re-sent statements safe to process.

Development

uv sync
uv run ruff check src tests
uv run pytest          # offline — fake YNAB over httpx.MockTransport
uv run python scripts/smoke.py http://127.0.0.1:8000   # against a running server

Deployment

deploy/ contains a ready-made Dockge/compose stack: internal-only network, no published ports, GHCR image with pull_policy: always, secrets via the stack .env, rollback by pinning a :sha-<commit> tag.

Design

See docs/design.md for the full design and rationale.

License

MIT — see LICENSE.

Available Tools

6 tools
auth_statusA
Read-only

Check the YNAB connection: token validity, plan list, and this server's configuration (writes on/off, dedupe window). Never returns the token.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

The readOnlyHint annotation already signals a safe read operation, and the description adds meaningful context beyond that: it discloses that the token is never returned, a valuable confidentiality guarantee. It also clarifies that server configuration state (writes on/off, dedupe window) is included. It does not address behavior on invalid tokens, but the output schema likely covers response 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 tightly written sentence with a colon-delimited list conveys all key behaviors. It is front-loaded with the primary purpose and contains no filler or repetition.

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 parameterless status-check tool with an output schema and a read-only annotation, the description covers the essentials: what is checked, what configuration is included, and a critical security guarantee. Nothing needed to invoke it correctly is missing.

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 trivially complete. The description appropriately focuses on what the tool returns and checks rather than inventing parameter details, matching the baseline for a parameterless tool.

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 ('Check') and resource ('the YNAB connection'), then enumerates exactly what is checked: token validity, plan list, and server configuration. This clearly distinguishes it from sibling data-listing tools like list_plans or 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 Guidelines3/5

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

The phrase 'Check the YNAB connection' implies this is a status/diagnostic tool to verify authentication and configuration. However, it does not explicitly state when to use this tool versus alternatives, nor when not to use it, leaving some guidance to inference.

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

get_transactionsA
Read-only

List transactions, newest first. Optional filters: one account, a date range (YYYY-MM-DD, inclusive), or only unapproved. Returns dollar amounts as strings plus exact milliunits. limit caps the rows returned (max 500).

ParametersJSON Schema
NameRequiredDescriptionDefault
planNo
limitNo
accountNo
since_dateNo
until_dateNo
unapproved_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

The readOnlyHint annotation already signals a non-mutating operation, and the description adds useful behavioral context by stating the sort order, the string versus milliunit return format, and the 500-row cap. This goes beyond the annotations without contradicting them.

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 composed of three compact sentences, each carrying useful information. It front-loads the core purpose, then covers filters, result format, and limits with no wasted words.

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 an output schema present, the description appropriately focuses on behavior and inputs. It covers sorting, filters, return encoding, and row limits, making the tool callable in most cases. The only notable gap is the unexplained `plan` parameter, which keeps it from being fully 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 description adds real meaning for account, since_date, until_date, unapproved_only, and limit, including date format, inclusivity, and the maximum limit. However, the `plan` parameter is not mentioned at all, and the mapping from 'date range' to the two date parameters is left implicit, so the agent still has to infer some schema details.

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 transactions with a specific sort order and describes the main filtering options. It is immediately distinguishable from the sibling tools, which target different resources like plans, payees, accounts, and categories.

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 makes it clear this is the transaction-listing tool, so when an agent needs transactions this is the obvious choice. However, it does not explicitly discuss when not to use it or mention alternatives, leaving usage guidance largely 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.

list_accountsA
Read-only

List accounts in a plan: id, name, type, on-budget flag, balance. Closed accounts are hidden unless include_closed=true.

ParametersJSON Schema
NameRequiredDescriptionDefault
planNo
include_closedNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

The readOnlyHint=true annotation already covers the safety profile. The description adds meaningful behavioral context beyond the annotation by disclosing that closed accounts are hidden unless include_closed=true, and by specifying the returned fields. It does not cover plan-null behavior or pagination, but the extra context justifies a strong score.

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 entire description is one tightly structured sentence: action, field list, then the conditional filter behavior. Every phrase contributes information, with the core purpose front-loaded and no filler.

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 two-parameter list tool with an output schema and a read-only annotation, the description covers the essential fields and the key filtering behavior. The main gap is the ambiguous 'plan' parameter defaulting to null, which leaves the agent unsure whether omitting it lists all plans or requires a plan identifier.

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?

With 0% schema description coverage, the description carries the burden of explaining both parameters. It clearly explains include_closed via the 'unless include_closed=true' clause, but 'plan' is only glossed as 'in a plan' without clarifying the default null semantics (e.g., all plans vs current plan). Compensation is partial.

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 the specific verb 'List' and the resource 'accounts', and enumerates the exact fields returned (id, name, type, on-budget flag, balance). It is immediately distinguishable from siblings like list_plans, list_payees, and list_categories, which target different resources.

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

Usage Guidelines3/5

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

The intended use case is implied by the resource and the 'in a plan' qualifier, but no explicit guidance is given for when to choose this over alternatives. There are no exclusions or comparisons to siblings, so the agent must rely on the name to infer applicability.

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

list_categoriesA
Read-only

List categories in a plan: id, group, name, and budgeted/activity/balance for the current month. Hidden categories are excluded unless include_hidden=true; search matches name or group (substring).

ParametersJSON Schema
NameRequiredDescriptionDefault
planNo
searchNo
include_hiddenNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already establish read-only behavior. The description adds meaningful non-obvious behaviors: results are scoped to the current month, hidden categories are excluded unless include_hidden=true, and search is a substring match on name or group. These are exactly the details an agent needs to interpret results correctly.

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 first states the outcome and output fields, the second covers filtering and search semantics. Information is front-loaded and every clause 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?

The description covers output fields, time scope, hidden-category behavior, and search matching, and an output schema exists to document return values. However, the plan parameter remains underspecified, which is important because all parameters are optional and the description still frames the tool as operating 'in a plan.'

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?

With 0% schema description coverage, the description carries the semantic burden for parameters. It explains include_hidden and search well, but the plan parameter is only implied by 'in a plan' and does not clarify whether it expects an ID, name, or null/default behavior. This is a meaningful gap for a tool with no required parameters.

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 ('List') on a clear resource ('categories in a plan') and enumerates the returned fields. It is immediately distinguishable from sibling tools that work on plans, accounts, payees, or 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?

The description gives clear context for when to use it: any time an agent needs category-level budget/activity/balance data, with explicit notes on filtering. It does not explicitly name alternatives or state when not to use it, so it stops short of the strongest possible guidance.

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

list_payeesA
Read-only

List payees in a plan: id, name, and the transfer target account for transfer payees. search matches the name (substring).

ParametersJSON Schema
NameRequiredDescriptionDefault
planNo
searchNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

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

The annotations already declare the tool read-only, so the description does not need to restate that. It adds useful behavioral details: the search parameter matches the name as a substring, and transfer payees include a transfer target account. This goes beyond the structured annotations.

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

Conciseness5/5

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

The description is a single, tightly written sentence that front-loads the action and key output fields. There is no redundancy or filler; every clause adds value.

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 tool's core purpose, output fields, and search behavior, and an output schema exists. However, it leaves the 'plan' parameter ambiguous and does not mention potential pagination or sorting, which an agent might need. It is adequate but not exhaustive.

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?

With 0% schema coverage, the description carries the burden of explaining parameters. It describes the 'search' parameter's substring matching behavior, but does not explain what 'plan' refers to or how it filters results. This is a partial compensation only.

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 it lists payees in a plan and specifies the returned fields (id, name, transfer target account). It is specific and actionable, but it does not explicitly differentiate from sibling tools like list_plans or list_accounts, so it stops short of a 5.

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 on when to use this tool versus the sibling list tools. The search feature is mentioned but there is no context about when to invoke this tool or when an alternative would be more appropriate.

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

list_plansA
Read-only

List the plans (budgets) on this YNAB account: id, name, last month, currency.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint: true, so the description does not need to restate safety. It adds useful context by clarifying that 'plans' are 'budgets' and by specifying the returned fields, which goes beyond the bare annotation. No behavioral contradictions exist.

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, the resource, and the key returned fields. There is no filler or redundant information; every word 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, parameterless list tool, the description is complete: it names the resource, clarifies terminology, and lists the returned fields. The output schema handles the full return structure, and annotations cover the read-only nature. An agent has everything needed to invoke it correctly.

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, and the input schema is empty with 100% schema description coverage, so there are no parameter semantics to document. The description's mention of output fields is extra and not required. Baseline for zero-parameter tools is 4.

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 ('List') and identifies the resource as 'plans (budgets)' on the YNAB account. It also names the returned fields (id, name, last month, currency), which clearly distinguishes it from sibling list tools like list_accounts and list_payees. No tautology; an agent immediately knows what this tool does.

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

Usage Guidelines4/5

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

The description clearly implies when to use this tool: when you need the budget plans for the current YNAB account. It does not explicitly name alternatives or exclusion criteria, but the distinct resource and simple parameterless nature make the usage context clear. Sibling tools target different entities, so the risk of confusion is low.

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. 6 tool updatesv0.1.0
    • First observedauth_status
    • First observedget_transactions
    • First observedlist_accounts
    • First observedlist_categories
    • First observedlist_payees
    • First observedlist_plans

TDQS

A4.1/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct YNAB resource or concern: plans, transactions, payees, auth, accounts, and categories. There is no overlap between them.

Naming Consistency4/5

Most tools follow a consistent list_<resource> pattern. get_transactions and auth_status deviate slightly but are still clear and predictable.

Tool Count5/5

Six tools is well-scoped for a lightweight YNAB server, covering all essential read-only resources without unnecessary bloat.

Completeness4/5

The read-only surface is complete for YNAB: plans, accounts, transactions, payees, categories, and authentication status are all covered. Write operations are absent, but this is a 'lite' server; the auth_status mention of writes feels slightly disconnected.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables interaction with You Need A Budget (YNAB) through their API, allowing users to manage budgets, accounts, categories, transactions, payees, and scheduled transactions through natural language.
    12
    10 npm
    1
    GPL 3.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to interact with YNAB budgets, performing read-only queries by default and optional write operations like creating transactions and managing categories through natural language.
    39
    223 npm
    33
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables users to interact with YNAB budgets, accounts, transactions, and more through a comprehensive set of tools with batch operations, deterministic analysis, and undo support.
    26
    48 npm
    5
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables reading and writing YNAB budget data, such as listing budgets, accounts, categories, transactions, and creating or updating transactions, through natural language commands.
    8
    MIT