ynab-mcp-lite
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ynab-mcp-liteshow me unapproved transactions from my checking account this month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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
GETrequests 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=falseafter 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 |
| token validity, plan list, server config |
| plans (budgets) on the account |
| accounts: id, name, type, on-budget, balance |
| categories + groups, budgeted/activity/balance |
| payees, optional name search |
| transactions, filter by account / dates / unapproved |
Add-only writes (registered only when YNAB_ALLOW_WRITES=1)
tool | description |
| add one transaction (dry-run default) |
| 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=1on 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:latestMCP 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 stdioUse 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 Personal Access Token (Settings → Developer) |
|
|
|
| — | default plan id; a single plan resolves automatically |
|
| duplicate pre-check window, in days |
| container name + localhost | Host allowlist for the HTTP transport |
|
| API base (development only) |
|
| bind address for |
Reconciliation workflow
The reason the write path exists: reconciling a card or account against a statement / receipt screenshots.
Pull what's already recorded:
get_transactionsfor the account and date range.Diff against the statement (anywhere: chat, script, human).
Preview the additions with
create_transaction(s)(dry-run default).Create them for real (
dry_run=false) — all unapproved, optionally flagged for easy review.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 serverDeployment
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 toolsauth_statusARead-only
Check the YNAB connection: token validity, plan list, and this server's configuration (writes on/off, dedupe window). Never returns the token.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
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.
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.
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.
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.
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.
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_transactionsARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| plan | No | ||
| limit | No | ||
| account | No | ||
| since_date | No | ||
| until_date | No | ||
| unapproved_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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_accountsARead-only
List accounts in a plan: id, name, type, on-budget flag, balance. Closed accounts are hidden unless include_closed=true.
| Name | Required | Description | Default |
|---|---|---|---|
| plan | No | ||
| include_closed | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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_categoriesARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| plan | No | ||
| search | No | ||
| include_hidden | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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_payeesARead-only
List payees in a plan: id, name, and the transfer target account for transfer payees. search matches the name (substring).
| Name | Required | Description | Default |
|---|---|---|---|
| plan | No | ||
| search | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare 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.
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.
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.
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.
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.
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_plansARead-only
List the plans (budgets) on this YNAB account: id, name, last month, currency.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint: true, 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.
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.
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.
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.
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.
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.
6 tool updates
v0.1.0- First observed
auth_status - First observed
get_transactions - First observed
list_accounts - First observed
list_categories - First observed
list_payees - First observed
list_plans
TDQS
Scored across 6 tools
Each tool targets a distinct YNAB resource or concern: plans, transactions, payees, auth, accounts, and categories. There is no overlap between them.
Most tools follow a consistent list_<resource> pattern. get_transactions and auth_status deviate slightly but are still clear and predictable.
Six tools is well-scoped for a lightweight YNAB server, covering all essential read-only resources without unnecessary bloat.
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
Related MCP Connectors
Read your accounts, budgets and net worth, and draft changes you confirm.
Read-only access to your bank, investment, and crypto accounts: balances, transactions, holdings.
Read-only access to your net worth, wealth percentile, projections, splits and budget.
Read-only Lunch Money accounts, transactions, categories and budgets. Unofficial connector.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables interaction with You Need A Budget (YNAB) through their API, allowing users to manage budgets, accounts, categories, transactions, payees, and scheduled transactions through natural language.1210 npm1GPL 3.0
- AlicenseAqualityBmaintenanceEnables 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.39223 npm33MIT
- AlicenseAqualityBmaintenanceEnables users to interact with YNAB budgets, accounts, transactions, and more through a comprehensive set of tools with batch operations, deterministic analysis, and undo support.2648 npm5MIT
- AlicenseAqualityBmaintenanceEnables reading and writing YNAB budget data, such as listing budgets, accounts, categories, transactions, and creating or updating transactions, through natural language commands.8MIT