@oliverames/ynab-mcp-server 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -51
- package/docs/privacy.md +51 -0
- package/index.js +489 -78
- package/package.json +13 -6
- package/scripts/build-mcpb.mjs +5 -5
- package/scripts/check-release-consistency.mjs +3 -3
- package/scripts/test-safety-model.mjs +120 -3
package/README.md
CHANGED
|
@@ -2,29 +2,29 @@
|
|
|
2
2
|
<img src="assets/icon.png" width="80" height="80" alt="YNAB">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">
|
|
5
|
+
<h1 align="center">MCP Server for YNAB</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong>
|
|
8
|
+
<strong>A local Model Context Protocol server for YNAB budget operations</strong><br>
|
|
9
9
|
<em>Give your AI assistant read-only budget access by default, with explicit write opt-in</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<code>47 tools with writes enabled</code> •
|
|
14
|
-
<code>
|
|
15
|
-
<code>
|
|
14
|
+
<code>YNAB API v1.85</code> •
|
|
15
|
+
<code>read-only by default</code>
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
19
|
<a href="https://www.npmjs.com/package/@oliverames/ynab-mcp-server"><img src="https://img.shields.io/npm/v/%40oliverames%2Fynab-mcp-server?style=flat-square&color=f5a542" alt="npm"></a>
|
|
20
|
-
<a href="https://github.com/oliverames/ynab-mcp-server/releases/tag/v2.1.1"><img src="https://img.shields.io/github/v/release/oliverames/ynab-mcp-server?style=flat-square&color=f5a542&label=MCPB" alt="MCPB release"></a>
|
|
21
20
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-f5a542?style=flat-square" alt="License"></a>
|
|
22
21
|
<a href="https://www.buymeacoffee.com/oliverames"><img src="https://img.shields.io/badge/Buy_Me_a_Coffee-support-f5a542?style=flat-square&logo=buy-me-a-coffee&logoColor=white" alt="Buy Me a Coffee"></a>
|
|
23
22
|
</p>
|
|
24
23
|
|
|
25
24
|
<p align="center">
|
|
26
25
|
<a href="#quick-start">Quick Start</a> •
|
|
27
|
-
<a href="#install-
|
|
26
|
+
<a href="#install-in-claude-code">Claude Code</a> •
|
|
27
|
+
<a href="#install-in-codex">Codex</a> •
|
|
28
28
|
<a href="#what-you-can-do">What You Can Do</a> •
|
|
29
29
|
<a href="#tools-reference">Tools Reference</a> •
|
|
30
30
|
<a href="#environment-variables">Configuration</a>
|
|
@@ -36,25 +36,119 @@
|
|
|
36
36
|
|
|
37
37
|
YNAB's budgeting philosophy works best when you interact with your budget frequently - but the app interface isn't designed for quick queries or bulk operations. "How much did I spend on groceries this month?" shouldn't require navigating three screens. "Categorize all my Amazon orders from this week" shouldn't be a manual, one-by-one process.
|
|
38
38
|
|
|
39
|
-
This server gives your AI assistant a safe interface to YNAB's API, turning natural language into budget review and, when explicitly enabled, budget operations. All monetary values are automatically converted between dollars and YNAB's internal milliunits format so the AI never has to think about it. Built on the [official YNAB JavaScript SDK](https://github.com/ynab/ynab-sdk-js) with direct API calls for
|
|
39
|
+
This server gives your AI assistant a safe local interface to YNAB's API, turning natural language into budget review and, when explicitly enabled, budget operations. All monetary values are automatically converted between dollars and YNAB's internal milliunits format so the AI never has to think about it. Built on the [official YNAB JavaScript SDK](https://github.com/ynab/ynab-sdk-js) with direct API calls for endpoints and query parameters that the SDK has not caught up with yet.
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
43
|
## Quick Start
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
This package stands on its own as a stdio MCP server. You do not need a Claude or Codex marketplace plugin; install it directly with `npx` and your MCP client will launch it on demand.
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
### 1. Get a YNAB Personal Access Token
|
|
48
48
|
|
|
49
|
-
[
|
|
49
|
+
Go to [YNAB Developer Settings](https://app.ynab.com/settings/developer) and create a new personal access token.
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
This local stdio package is intended for a YNAB account owner running the server for their own account. A public hosted connector for other YNAB users must use YNAB OAuth instead of asking users for personal access tokens; see [docs/hosted-oauth-connector.md](docs/hosted-oauth-connector.md).
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Credential lookup order:
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
1. Values passed directly to the MCP process, such as `YNAB_API_TOKEN`.
|
|
56
|
+
2. Codex plaintext settings in `~/.codex/config.toml`, first `[shell_environment_policy.set]`, then `[mcp_servers.ynab.env]`.
|
|
57
|
+
3. Claude Code plaintext settings in `~/.claude/settings.json` under top-level `env`.
|
|
58
|
+
4. `YNAB_API_TOKEN_FILE`, if configured in any of the sources above.
|
|
59
|
+
5. `YNAB_OP_PATH`, if configured in any of the sources above and the `op` CLI is available.
|
|
60
|
+
|
|
61
|
+
If no token is found, `ynab_auth_status` returns a structured setup guide. Agents should first ask whether the user already has the YNAB token in a password manager such as 1Password. If yes, ask permission before configuring `YNAB_OP_PATH`; otherwise ask the user to add `YNAB_API_TOKEN` to the correct Codex or Claude config file and restart the MCP server.
|
|
62
|
+
|
|
63
|
+
### 2. Install in Claude Code
|
|
64
|
+
|
|
65
|
+
Use user scope if you want the server available in all Claude Code projects:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
claude mcp add ynab --scope user \
|
|
69
|
+
-e YNAB_API_TOKEN=your-token-here \
|
|
70
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add a default budget ID if you do not want tools to use YNAB's `last-used` budget:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
claude mcp add ynab --scope user \
|
|
77
|
+
-e YNAB_API_TOKEN=your-token-here \
|
|
78
|
+
-e YNAB_BUDGET_ID=optional-default-budget-id \
|
|
79
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use `--scope project` instead of `--scope user` if you want Claude Code to write a project-local `.mcp.json`.
|
|
83
|
+
|
|
84
|
+
If `~/.claude/settings.json` already contains `env.YNAB_API_TOKEN`, you may omit `-e YNAB_API_TOKEN=...`; the server will read the Claude setting as a fallback if the launcher does not inject it.
|
|
85
|
+
|
|
86
|
+
Verify Claude Code can see the server:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
claude mcp get ynab
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If Claude Code reports that `ynab` already exists, remove the old entry and run the add command again:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
claude mcp remove ynab
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Install in Codex
|
|
99
|
+
|
|
100
|
+
Register the same npm package directly with Codex:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
codex mcp add ynab \
|
|
104
|
+
--env YNAB_API_TOKEN=your-token-here \
|
|
105
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
With a default budget ID:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
codex mcp add ynab \
|
|
112
|
+
--env YNAB_API_TOKEN=your-token-here \
|
|
113
|
+
--env YNAB_BUDGET_ID=optional-default-budget-id \
|
|
114
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If `~/.codex/config.toml` already contains `YNAB_API_TOKEN` under `[shell_environment_policy.set]` or `[mcp_servers.ynab.env]`, you may omit `--env YNAB_API_TOKEN=...`; the server will read the Codex setting as a fallback if the launcher does not inject it.
|
|
118
|
+
|
|
119
|
+
Verify Codex can see the server:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
codex mcp get ynab
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
If Codex reports that `ynab` already exists, remove the old entry and run the add command again:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
codex mcp remove ynab
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 4. Enable Write Tools (Optional)
|
|
56
132
|
|
|
57
|
-
|
|
133
|
+
By default, the server registers read-only tools only. To expose tools that create, update, import, or delete YNAB data, add `YNAB_ALLOW_WRITES=1` when you register the server:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
claude mcp add ynab --scope user \
|
|
137
|
+
-e YNAB_API_TOKEN=your-token-here \
|
|
138
|
+
-e YNAB_ALLOW_WRITES=1 \
|
|
139
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
codex mcp add ynab \
|
|
144
|
+
--env YNAB_API_TOKEN=your-token-here \
|
|
145
|
+
--env YNAB_ALLOW_WRITES=1 \
|
|
146
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Bulk-filter write tools such as `approve_transactions`, `reassign_payee_transactions`, and the generic `ynab_write_tool_execute` helper also require `confirmed: true` in the tool input after explicit user confirmation. For extra protection, pass `expectedMatchedCount` when using bulk-filter writes.
|
|
150
|
+
|
|
151
|
+
### Manual JSON Config
|
|
58
152
|
|
|
59
153
|
**Claude Desktop** (`claude_desktop_config.json`):
|
|
60
154
|
|
|
@@ -72,7 +166,7 @@ Go to [YNAB Developer Settings](https://app.ynab.com/settings/developer) and cre
|
|
|
72
166
|
}
|
|
73
167
|
```
|
|
74
168
|
|
|
75
|
-
**
|
|
169
|
+
**Generic MCP client**:
|
|
76
170
|
|
|
77
171
|
```json
|
|
78
172
|
{
|
|
@@ -88,7 +182,7 @@ Go to [YNAB Developer Settings](https://app.ynab.com/settings/developer) and cre
|
|
|
88
182
|
}
|
|
89
183
|
```
|
|
90
184
|
|
|
91
|
-
|
|
185
|
+
If you prefer a global install, point your MCP client at the package binary directly:
|
|
92
186
|
|
|
93
187
|
```bash
|
|
94
188
|
npm install -g @oliverames/ynab-mcp-server
|
|
@@ -98,7 +192,7 @@ npm install -g @oliverames/ynab-mcp-server
|
|
|
98
192
|
{
|
|
99
193
|
"mcpServers": {
|
|
100
194
|
"ynab": {
|
|
101
|
-
"command": "
|
|
195
|
+
"command": "mcp-server-for-ynab",
|
|
102
196
|
"env": {
|
|
103
197
|
"YNAB_API_TOKEN": "your-token-here",
|
|
104
198
|
"YNAB_BUDGET_ID": "optional-default-budget-id"
|
|
@@ -108,23 +202,28 @@ npm install -g @oliverames/ynab-mcp-server
|
|
|
108
202
|
}
|
|
109
203
|
```
|
|
110
204
|
|
|
111
|
-
|
|
205
|
+
### 1Password Token Lookup (Optional)
|
|
112
206
|
|
|
113
|
-
|
|
207
|
+
If your token is stored in 1Password, set `YNAB_OP_PATH` instead of `YNAB_API_TOKEN`. The `op` CLI must be installed and authenticated in the environment that launches the MCP server.
|
|
114
208
|
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
209
|
+
```bash
|
|
210
|
+
claude mcp add ynab --scope user \
|
|
211
|
+
-e YNAB_OP_PATH="op://Personal/YNAB API Token/credential" \
|
|
212
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
codex mcp add ynab \
|
|
217
|
+
--env 'YNAB_OP_PATH=op://Personal/YNAB API Token/credential' \
|
|
218
|
+
-- npx -y @oliverames/ynab-mcp-server@latest
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Local Smoke Test
|
|
222
|
+
|
|
223
|
+
From this repo, you can verify the published npm package without changing any MCP client config:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
YNAB_API_TOKEN=your-token-here npm run smoke:review-unapproved -- --published
|
|
128
227
|
```
|
|
129
228
|
|
|
130
229
|
---
|
|
@@ -148,7 +247,7 @@ By default, the server registers read-only tools only. To expose tools that crea
|
|
|
148
247
|
|
|
149
248
|
## Features
|
|
150
249
|
|
|
151
|
-
**
|
|
250
|
+
**YNAB API v1.85 coverage** with 47 tools when writes are enabled:
|
|
152
251
|
|
|
153
252
|
| Resource | Tools | Capabilities |
|
|
154
253
|
|----------|-------|-------------|
|
|
@@ -169,13 +268,14 @@ By default, the server registers read-only tools only. To expose tools that crea
|
|
|
169
268
|
- **Dollar amounts everywhere** - inputs and outputs are in dollars (`-12.34`), never milliunits (`-12340`). Conversion is automatic and transparent.
|
|
170
269
|
- **Smart budget resolution** - set `YNAB_BUDGET_ID` for a default, or omit it to auto-resolve to your last-used budget. Every tool accepts an optional `budgetId` override.
|
|
171
270
|
- **Pinned YNAB host** - all HTTP requests are restricted to `https://api.ynab.com`, redirects are not followed, and API tokens are redacted from surfaced errors.
|
|
172
|
-
- **
|
|
271
|
+
- **Agent-aware token fallback** - use direct process env, Codex `~/.codex/config.toml`, Claude `~/.claude/settings.json`, a small token file via `YNAB_API_TOKEN_FILE`, or a 1Password CLI reference via `YNAB_OP_PATH`.
|
|
173
272
|
- **Split transactions** - first-class support for subtransactions in create, read, and format operations.
|
|
273
|
+
- **Current transaction filters** - transaction list tools support `sinceDate`, `untilDate`, type filters, resource filters, and delta requests. YNAB defaults omitted `sinceDate` to one year ago, so pass an explicit older date when you need older history.
|
|
174
274
|
- **Bulk operations** - `create_transactions` and `update_transactions` handle arrays in a single API call.
|
|
175
275
|
- **Verified batch updates** - `update_transactions` refetches every requested transaction after the bulk API call, retries mismatched fields once through `update_transaction`, and returns a `verification` block so approval counts cannot hide failed category writes.
|
|
176
276
|
- **Fetch-then-merge updates** - scheduled transaction updates (which use PUT semantics) automatically fetch the current state and merge your changes, so you only specify what changed.
|
|
177
277
|
- **Fuzzy search** - `search_categories` and `search_payees` do case-insensitive partial matching across all entries.
|
|
178
|
-
- **Approval workflow with anomaly flags** - `review_unapproved` groups transactions into "ready to approve" (categorized, split, or transfer) and "needs attention" (uncategorized), and attaches a `flags` array to each transaction surfacing anomalies: `manually_entered` (not bank-imported), `match_broken` (stale match reference), `scheduled_transaction_realized`, `new_payee`, `no_prior_amount_match` (novel amount for this payee), and `category_drift:was_X` (payee categorized differently in the prior 60 days). Group-level flags aggregate the union of all transaction flags.
|
|
278
|
+
- **Approval workflow with anomaly flags** - `review_unapproved` groups transactions into "ready to approve" (categorized, split, or transfer) and "needs attention" (uncategorized), and attaches a `flags` array to each transaction surfacing anomalies: `manually_entered` (not bank-imported), `match_broken` (stale match reference), `scheduled_transaction_realized`, `new_payee`, `no_prior_amount_match` (novel amount for this payee), and `category_drift:was_X` (payee categorized differently in the prior 60 days). Group-level flags aggregate the union of all transaction flags. Bulk approval requires `confirmed: true`.
|
|
179
279
|
- **Nullable updates** - update tools accept `null` for clearable fields (`memo`, `payeeName`, `categoryId`, `flagColor`) to distinguish "don't change" (omit) from "clear this field" (`null`).
|
|
180
280
|
- **Target behavior support** - category create/update tools expose `goalNeedsWholeAmount` for YNAB's "Set aside another" vs. "Refill up to" goal behavior.
|
|
181
281
|
- **Delta request support** - high-volume list tools accept `lastKnowledgeOfServer` and return `server_knowledge` when that parameter is provided.
|
|
@@ -258,14 +358,14 @@ Read tools are available by default. Tools that create, update, import, or delet
|
|
|
258
358
|
|
|
259
359
|
| Tool | Description |
|
|
260
360
|
|------|-------------|
|
|
261
|
-
| `get_transactions` | Get transactions with filters: by account, category, payee, month,
|
|
361
|
+
| `get_transactions` | Get transactions with filters: by account, category, payee, month, status (`unapproved`/`uncategorized`), `sinceDate`, and `untilDate` |
|
|
262
362
|
| `get_transaction` | Get a single transaction by ID (includes subtransactions). Auto-handles composite scheduled-transaction IDs like `uuid_YYYY-MM-DD`; if the underlying matched transaction has been deleted, falls back to returning the active scheduled template wrapped as `{ resource_type: "scheduled_transaction", ... }`. |
|
|
263
363
|
| `create_transaction` | Write tool: create a transaction with optional split (subtransactions must sum to total) |
|
|
264
364
|
| `create_transactions` | Write tool: bulk create multiple transactions in a single API call (supports split transactions) |
|
|
265
365
|
| `update_transaction` | Write tool: partial update - only specified fields change |
|
|
266
366
|
| `update_transactions` | Write tool: batch update multiple transactions at once, then refetch and verify requested fields persisted. Pass `returnSummary: true` for compact counts instead of full objects on large batches (avoids overflowing the tool-result size limit). |
|
|
267
|
-
| `approve_transactions` | Write tool: approve unapproved transactions in bulk by filter (`payeeId` / `categoryId` / `accountId`) without hand-listing IDs. Skips uncategorized transactions by default
|
|
268
|
-
| `reassign_payee_transactions` | Write tool: move all transactions from one payee to another
|
|
367
|
+
| `approve_transactions` | Write tool: approve unapproved transactions in bulk by filter (`payeeId` / `categoryId` / `accountId`) without hand-listing IDs. Skips uncategorized transactions by default, requires `confirmed: true`, and supports `expectedMatchedCount`. |
|
|
368
|
+
| `reassign_payee_transactions` | Write tool: move all transactions from one payee to another, the merge workaround since the YNAB API has no payee delete/merge endpoint. Requires `confirmed: true` and supports `expectedMatchedCount`. |
|
|
269
369
|
| `delete_transaction` | Write tool: delete a transaction |
|
|
270
370
|
| `import_transactions` | Write tool: trigger import from linked bank accounts |
|
|
271
371
|
|
|
@@ -298,6 +398,18 @@ The server starts in read-only mode. Write tools are not merely discouraged; the
|
|
|
298
398
|
|
|
299
399
|
If a client already has the process running, changing the environment is not enough. Restart the MCP server after setting or clearing `YNAB_ALLOW_WRITES`.
|
|
300
400
|
|
|
401
|
+
Bulk-filter writes require confirmation in the tool input, not only in surrounding chat:
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"confirmed": true,
|
|
406
|
+
"expectedMatchedCount": 3,
|
|
407
|
+
"payeeId": "payee-id-to-approve"
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
If `expectedMatchedCount` is provided and the current match count differs, the tool returns an error before mutating any transactions.
|
|
412
|
+
|
|
301
413
|
### Batch Updates
|
|
302
414
|
|
|
303
415
|
When a batch operation categorizes and approves transactions at the same time, do not use `review_unapproved` counts as the only success check. Approved transactions leave the review queue even if a category write failed, so queue counts can hide approved-but-still-uncategorized transactions.
|
|
@@ -328,17 +440,18 @@ Manual YNAB transfer fixes can replace one side of the pair with a new transacti
|
|
|
328
440
|
|
|
329
441
|
| Variable | Required | Description |
|
|
330
442
|
|----------|----------|-------------|
|
|
331
|
-
| `YNAB_API_TOKEN` | Yes* | [Personal access token](https://app.ynab.com/settings/developer) from YNAB Developer Settings. |
|
|
332
|
-
| `YNAB_API_TOKEN_FILE` | No | Path to a file containing the token. The file must be 4 KB or smaller. Used only when `YNAB_API_TOKEN` is unset. |
|
|
443
|
+
| `YNAB_API_TOKEN` | Yes* | [Personal access token](https://app.ynab.com/settings/developer) from YNAB Developer Settings. Read from process env first, then Codex and Claude plaintext agent settings. |
|
|
444
|
+
| `YNAB_API_TOKEN_FILE` | No | Path to a file containing the token. The file must be 4 KB or smaller. Used only when `YNAB_API_TOKEN` is unset. Can be provided through process env or agent settings. |
|
|
333
445
|
| `YNAB_BUDGET_ID` | No | Default budget ID. If omitted, uses `"last-used"` (your most recently accessed budget). Run `list_budgets` to find IDs. |
|
|
334
446
|
| `YNAB_ALLOW_WRITES` | No | Set to `1` to register write tools. Any other value keeps the server read-only. |
|
|
335
|
-
| `YNAB_OP_PATH` | No | 1Password secret reference for your API token (see below). Required only if using the 1Password fallback instead of `YNAB_API_TOKEN`. |
|
|
447
|
+
| `YNAB_OP_PATH` | No | 1Password secret reference for your API token (see below). Required only if using the 1Password fallback instead of `YNAB_API_TOKEN`. Can be provided through process env or agent settings. |
|
|
448
|
+
| `YNAB_DISABLE_AGENT_CONFIG_FALLBACK` | No | Set to `1` to stop the server from reading `~/.codex/config.toml` and `~/.claude/settings.json`. Intended for tests and tightly controlled runtimes. |
|
|
336
449
|
| `YNAB_RATE_LIMIT_PER_HOUR` | No | Client-side rate limiter. Defaults to `190`; set to `0` to disable for controlled tests. |
|
|
337
450
|
| `YNAB_RATE_LIMIT_BURST` | No | Maximum burst size before rate limiting pauses requests. Defaults to `10`. |
|
|
338
451
|
| `YNAB_HTTP_TIMEOUT_MS` | No | Per-request timeout. Defaults to `30000`. |
|
|
339
452
|
| `YNAB_MAX_RESPONSE_BYTES` | No | Maximum direct-fetch response size for newer endpoints. Defaults to `8388608`. |
|
|
340
453
|
|
|
341
|
-
*`YNAB_API_TOKEN` is required unless `YNAB_API_TOKEN_FILE` or `YNAB_OP_PATH` is set.
|
|
454
|
+
*`YNAB_API_TOKEN` is required unless `YNAB_API_TOKEN_FILE` or `YNAB_OP_PATH` is set. These values may come from direct process env, Codex config, or Claude settings.
|
|
342
455
|
|
|
343
456
|
### 1Password Integration
|
|
344
457
|
|
|
@@ -358,7 +471,7 @@ If you store your YNAB token in [1Password CLI](https://developer.1password.com/
|
|
|
358
471
|
}
|
|
359
472
|
```
|
|
360
473
|
|
|
361
|
-
The fallback adds ~1-2s to startup and is silently skipped if `op` is unavailable or the item is not found.
|
|
474
|
+
The fallback adds ~1-2s to startup and is silently skipped if `op` is unavailable or the item is not found. If no token source is configured, `ynab_auth_status` tells the calling agent to ask whether you have a token in 1Password or another password manager, request permission before editing agent config, and otherwise ask you to add `YNAB_API_TOKEN` to the appropriate Codex or Claude settings file.
|
|
362
475
|
|
|
363
476
|
---
|
|
364
477
|
|
|
@@ -387,20 +500,21 @@ Set `YNAB_RATE_LIMIT_PER_HOUR=0` only for controlled local tests or smoke checks
|
|
|
387
500
|
|
|
388
501
|
```
|
|
389
502
|
┌─────────────────────┐ ┌──────────────────┐ ┌──────────────┐
|
|
390
|
-
│ AI Assistant │────▶│
|
|
391
|
-
│
|
|
503
|
+
│ AI Assistant │────▶│ MCP Server for │────▶│ YNAB API │
|
|
504
|
+
│ │ │ YNAB │ │ │
|
|
505
|
+
│ (Claude, GPT, etc) │◀────│ (this package) │◀────│ api.ynab.com│
|
|
392
506
|
└─────────────────────┘ └──────────────────┘ └──────────────┘
|
|
393
507
|
MCP stdio transport HTTPS/REST
|
|
394
508
|
```
|
|
395
509
|
|
|
396
510
|
- **Transport:** stdio (standard MCP server pattern)
|
|
397
|
-
- **Auth:** Bearer token via `YNAB_API_TOKEN`, `YNAB_API_TOKEN_FILE`, or `YNAB_OP_PATH`
|
|
398
|
-
- **SDK:** Official [`ynab`](https://www.npmjs.com/package/ynab)
|
|
511
|
+
- **Auth:** Bearer token via `YNAB_API_TOKEN`, `YNAB_API_TOKEN_FILE`, or `YNAB_OP_PATH` for local owner-run use
|
|
512
|
+
- **SDK:** Official [`ynab`](https://www.npmjs.com/package/ynab) v4.1+ for core endpoints, direct `fetch` for newer API features and v1.85 transaction filters
|
|
399
513
|
- **Safety:** read-only default, explicit write opt-in, host-pinned HTTPS requests to `api.ynab.com`, no redirect following, redacted token errors
|
|
400
514
|
- **Validation:** All parameters validated with [Zod](https://zod.dev) schemas
|
|
401
515
|
- **Error handling:** API errors are caught, formatted, and returned as MCP error responses with detail messages
|
|
402
516
|
|
|
403
|
-
For a hosted OAuth connector design, see [docs/hosted-oauth-connector.md](docs/hosted-oauth-connector.md).
|
|
517
|
+
For a hosted OAuth connector design, see [docs/hosted-oauth-connector.md](docs/hosted-oauth-connector.md). For data handling details for this local package, see [docs/privacy.md](docs/privacy.md).
|
|
404
518
|
|
|
405
519
|
---
|
|
406
520
|
|
|
@@ -418,7 +532,7 @@ Tests cover all tool categories: reads, reversible writes, bulk operations, sear
|
|
|
418
532
|
|
|
419
533
|
### MCP Smoke Tests
|
|
420
534
|
|
|
421
|
-
Use the smoke tests when you need to prove the server is reachable over stdio without reconstructing a custom MCP client. These commands use the official MCP SDK client, the same transport shape used by normal MCP hosts, and require `YNAB_API_TOKEN`
|
|
535
|
+
Use the smoke tests when you need to prove the server is reachable over stdio without reconstructing a custom MCP client. These commands use the official MCP SDK client, the same transport shape used by normal MCP hosts. `smoke:list-tools` can run without a live token to verify discovery, but live read and write smokes require `YNAB_API_TOKEN`, `YNAB_API_TOKEN_FILE`, or `YNAB_OP_PATH`.
|
|
422
536
|
|
|
423
537
|
```bash
|
|
424
538
|
YNAB_API_TOKEN=your-token YNAB_BUDGET_ID=your-budget-id npm run smoke:list-tools
|
|
@@ -460,11 +574,20 @@ Before publishing, run:
|
|
|
460
574
|
|
|
461
575
|
```bash
|
|
462
576
|
npm run release:check
|
|
463
|
-
npm run build:mcpb
|
|
464
577
|
npm pack --dry-run
|
|
465
578
|
```
|
|
466
579
|
|
|
467
|
-
After publishing, run `npm run release:check:registry` to verify the npm `latest` dist-tag
|
|
580
|
+
After publishing, run `npm run release:check:registry` to verify the npm `latest` dist-tag and repo metadata agree on the same version. `npm run build:mcpb` remains available for an explicit local bundle, but the normal install path is direct MCP registration through npm.
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## Privacy and Non-Affiliation
|
|
585
|
+
|
|
586
|
+
See [docs/privacy.md](docs/privacy.md) for this connector's data handling, deletion, and token-use details.
|
|
587
|
+
|
|
588
|
+
This connector is not affiliated, associated, or in any way officially connected with YNAB or any of its subsidiaries or affiliates. The official YNAB website can be found at [https://www.ynab.com](https://www.ynab.com/).
|
|
589
|
+
|
|
590
|
+
The names YNAB and You Need A Budget, as well as related names, trade names, marks, trademarks, emblems, and images are registered trademarks of YNAB.
|
|
468
591
|
|
|
469
592
|
---
|
|
470
593
|
|
package/docs/privacy.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Privacy Policy for MCP Server for YNAB
|
|
2
|
+
|
|
3
|
+
Last Updated: June 8, 2026
|
|
4
|
+
|
|
5
|
+
MCP Server for YNAB is a local stdio MCP server that runs on the user's machine or in a user-controlled MCP host. It connects the user's MCP client to the YNAB API.
|
|
6
|
+
|
|
7
|
+
## Data Access
|
|
8
|
+
|
|
9
|
+
The server can access YNAB budget data that the configured YNAB access token is allowed to access, including budgets, accounts, categories, payees, transactions, scheduled transactions, months, and related metadata.
|
|
10
|
+
|
|
11
|
+
Write tools are disabled by default. They are registered only when `YNAB_ALLOW_WRITES=1` is set before the MCP process starts. Bulk-filter write tools also require `confirmed: true` in the tool input after explicit user confirmation.
|
|
12
|
+
|
|
13
|
+
## Data Storage
|
|
14
|
+
|
|
15
|
+
This package does not create a database and does not store YNAB budget data outside the running MCP process. It returns YNAB API responses to the connected MCP client so the client can answer the user's request.
|
|
16
|
+
|
|
17
|
+
Authentication is configured by the user through one of these local mechanisms:
|
|
18
|
+
|
|
19
|
+
- `YNAB_API_TOKEN`
|
|
20
|
+
- `YNAB_API_TOKEN_FILE`
|
|
21
|
+
- `YNAB_OP_PATH`
|
|
22
|
+
- Codex local plaintext settings in `~/.codex/config.toml`
|
|
23
|
+
- Claude Code local plaintext settings in `~/.claude/settings.json`
|
|
24
|
+
|
|
25
|
+
The server does not ask for, handle, or store bank credentials or other financial account login credentials.
|
|
26
|
+
|
|
27
|
+
## Data Sharing
|
|
28
|
+
|
|
29
|
+
This package sends YNAB API requests only to `https://api.ynab.com`. Outbound API requests are host-pinned to `api.ynab.com`, HTTPS-only, and redirects are not followed.
|
|
30
|
+
|
|
31
|
+
The package does not sell YNAB user data and does not intentionally share YNAB user data with third parties. The connected MCP host and AI assistant may receive tool results because that is the purpose of the MCP connection; users should review their MCP host's own privacy and retention policies.
|
|
32
|
+
|
|
33
|
+
## Logs and Diagnostics
|
|
34
|
+
|
|
35
|
+
The server redacts bearer tokens and authorization headers from surfaced errors. Users should still avoid pasting tokens, budget exports, or sensitive transaction details into public issues or support requests.
|
|
36
|
+
|
|
37
|
+
## Deleting Data
|
|
38
|
+
|
|
39
|
+
Because this local package does not persist YNAB budget data, there is no server-side data store to delete. To stop future access:
|
|
40
|
+
|
|
41
|
+
1. Remove the MCP server from the MCP host configuration.
|
|
42
|
+
2. Delete any local token file or environment variable used for `YNAB_API_TOKEN`.
|
|
43
|
+
3. Revoke the personal access token in YNAB Developer Settings.
|
|
44
|
+
|
|
45
|
+
If a hosted OAuth connector is deployed later, that hosted service must publish its own privacy policy, token storage details, and user-facing deletion or revocation flow.
|
|
46
|
+
|
|
47
|
+
## Non-Affiliation
|
|
48
|
+
|
|
49
|
+
This connector is not affiliated, associated, or in any way officially connected with YNAB or any of its subsidiaries or affiliates. The official YNAB website can be found at https://www.ynab.com/.
|
|
50
|
+
|
|
51
|
+
The names YNAB and You Need A Budget, as well as related names, trade names, marks, trademarks, emblems, and images are registered trademarks of YNAB.
|