@oliverames/ynab-mcp-server 2.1.0 → 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 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">YNAB MCP Server</h1>
5
+ <h1 align="center">MCP Server for YNAB</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>The complete Model Context Protocol server for YNAB</strong><br>
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> &bull;
14
- <code>100% API coverage</code> &bull;
15
- <code>YNAB API v1.83</code>
14
+ <code>YNAB API v1.85</code> &bull;
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.0"><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> &bull;
27
- <a href="#install-with-mcpb">MCPB Download</a> &bull;
26
+ <a href="#install-in-claude-code">Claude Code</a> &bull;
27
+ <a href="#install-in-codex">Codex</a> &bull;
28
28
  <a href="#what-you-can-do">What You Can Do</a> &bull;
29
29
  <a href="#tools-reference">Tools Reference</a> &bull;
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 the newest endpoints (category creation, category groups, money movements) that the SDK hasn't caught up with yet.
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
- ### Install with MCPB
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
- For Claude Desktop and other MCPB-compatible clients, download the local bundle from the [v2.0.0 release](https://github.com/oliverames/ynab-mcp-server/releases/tag/v2.1.0):
47
+ ### 1. Get a YNAB Personal Access Token
48
48
 
49
- [Download `ynab-mcp-server-2.1.0.mcpb`](https://github.com/oliverames/ynab-mcp-server/releases/download/v2.1.0/ynab-mcp-server-2.1.0.mcpb)
49
+ Go to [YNAB Developer Settings](https://app.ynab.com/settings/developer) and create a new personal access token.
50
50
 
51
- The bundle includes the YNAB favicon, production runtime dependencies, and setup prompts for your personal access token, optional default budget ID, and optional write-tool opt-in.
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
- ### 1. Get a YNAB Personal Access Token
53
+ Credential lookup order:
54
54
 
55
- Go to [YNAB Developer Settings](https://app.ynab.com/settings/developer) and create a new personal access token.
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
- ### 2. Configure your MCP client
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
- **Claude Code** (`.mcp.json`):
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
- Or install globally and point to the binary directly:
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": "ynab-mcp-server",
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
- That's it. Your AI can now talk to YNAB.
205
+ ### 1Password Token Lookup (Optional)
112
206
 
113
- 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` to the MCP server environment:
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
- ```json
116
- {
117
- "mcpServers": {
118
- "ynab": {
119
- "command": "npx",
120
- "args": ["-y", "@oliverames/ynab-mcp-server"],
121
- "env": {
122
- "YNAB_API_TOKEN": "your-token-here",
123
- "YNAB_ALLOW_WRITES": "1"
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
- **Complete YNAB API v1.83 coverage** with 47 tools when writes are enabled:
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
- - **Token fallback options** - use `YNAB_API_TOKEN`, a small token file via `YNAB_API_TOKEN_FILE`, or a 1Password CLI reference via `YNAB_OP_PATH`.
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, or status (`unapproved`/`uncategorized`) |
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; returns a compact summary. |
268
- | `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. |
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 │────▶│ YNAB MCP Server │────▶│ YNAB API │
391
- (Claude, GPT, etc) │◀────│ (this package) │◀────│ api.ynab.com
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) v2.5+ for core endpoints, direct `fetch` for newer API features
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` because this server validates credentials at startup.
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, repo metadata, README release links, and MCPB artifact references all agree on the same version.
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
 
@@ -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.