@dizzlkheinz/ynab-mcpb 0.16.1 → 0.17.1
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/.env.example +33 -33
- package/.github/workflows/ci-tests.yml +45 -45
- package/.github/workflows/claude-code-review.yml +57 -57
- package/.github/workflows/claude.yml +50 -50
- package/.github/workflows/full-integration.yml +22 -22
- package/.github/workflows/publish.yml +11 -2
- package/CLAUDE.md +33 -47
- package/README.md +8 -10
- package/dist/bundle/index.cjs +54 -54
- package/dist/server/YNABMCPServer.d.ts +120 -54
- package/dist/server/YNABMCPServer.js +28 -381
- package/dist/server/config.d.ts +2 -0
- package/dist/server/config.js +1 -0
- package/dist/server/securityMiddleware.d.ts +37 -8
- package/dist/tools/accountTools.d.ts +2 -0
- package/dist/tools/accountTools.js +45 -0
- package/dist/tools/adapters.d.ts +12 -0
- package/dist/tools/adapters.js +25 -0
- package/dist/tools/budgetTools.d.ts +2 -0
- package/dist/tools/budgetTools.js +30 -0
- package/dist/tools/categoryTools.d.ts +2 -0
- package/dist/tools/categoryTools.js +45 -0
- package/dist/tools/monthTools.d.ts +2 -0
- package/dist/tools/monthTools.js +32 -0
- package/dist/tools/payeeTools.d.ts +2 -0
- package/dist/tools/payeeTools.js +32 -0
- package/dist/tools/reconciliation/index.d.ts +2 -0
- package/dist/tools/reconciliation/index.js +33 -0
- package/dist/tools/schemas/common.d.ts +3 -0
- package/dist/tools/schemas/common.js +3 -0
- package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +1 -1
- package/dist/tools/schemas/outputs/index.d.ts +2 -2
- package/dist/tools/schemas/outputs/index.js +2 -2
- package/dist/tools/schemas/outputs/utilityOutputs.d.ts +0 -15
- package/dist/tools/schemas/outputs/utilityOutputs.js +0 -9
- package/dist/tools/transactionTools.d.ts +2 -0
- package/dist/tools/transactionTools.js +124 -0
- package/dist/tools/utilityTools.d.ts +2 -7
- package/dist/tools/utilityTools.js +19 -38
- package/dist/types/index.d.ts +1 -0
- package/dist/types/toolRegistration.d.ts +27 -0
- package/dist/types/toolRegistration.js +1 -0
- package/docs/maintainers/npm-publishing.md +27 -0
- package/docs/reference/API.md +15 -70
- package/docs/technical/reconciliation-system-architecture.md +2251 -2251
- package/package.json +6 -6
- package/scripts/analyze-bundle.mjs +41 -41
- package/scripts/generate-mcpb.ps1 +95 -95
- package/scripts/run-domain-integration-tests.js +4 -1
- package/scripts/watch-and-restart.ps1 +49 -49
- package/src/__tests__/comprehensive.integration.test.ts +0 -28
- package/src/__tests__/performance.test.ts +4 -12
- package/src/__tests__/setup.ts +45 -14
- package/src/__tests__/workflows.e2e.test.ts +1 -51
- package/src/server/YNABMCPServer.ts +33 -519
- package/src/server/__tests__/YNABMCPServer.test.ts +0 -1
- package/src/server/__tests__/toolRegistration.test.ts +236 -0
- package/src/server/config.ts +1 -0
- package/src/tools/__tests__/adapters.test.ts +113 -0
- package/src/tools/__tests__/transactionTools.integration.test.ts +63 -3
- package/src/tools/__tests__/utilityTools.integration.test.ts +1 -85
- package/src/tools/__tests__/utilityTools.test.ts +1 -123
- package/src/tools/accountTools.ts +53 -0
- package/src/tools/adapters.ts +74 -0
- package/src/tools/budgetTools.ts +37 -0
- package/src/tools/categoryTools.ts +53 -0
- package/src/tools/monthTools.ts +39 -0
- package/src/tools/payeeTools.ts +39 -0
- package/src/tools/reconciliation/index.ts +45 -0
- package/src/tools/schemas/common.ts +18 -0
- package/src/tools/schemas/outputs/index.ts +0 -3
- package/src/tools/schemas/outputs/utilityOutputs.ts +2 -43
- package/src/tools/toolCategories.ts +0 -1
- package/src/tools/transactionTools.ts +140 -0
- package/src/tools/utilityTools.ts +24 -55
- package/src/types/index.ts +3 -0
- package/src/types/toolRegistration.ts +88 -0
- package/vitest.config.ts +2 -1
- package/.chunkhound.json +0 -11
- package/.code/agents/01a13ef4-3f23-4f52-b33b-3585b73cfa60/error.txt +0 -3
- package/.code/agents/084fd32f-e298-4728-9103-a78d7dc39613/error.txt +0 -3
- package/.code/agents/0fed51e1-a943-4b97-a2a8-a6f0f27c844d/status.txt +0 -1
- package/.code/agents/1059b6bd-5ccd-4d83-a12c-7c9d89137399/error.txt +0 -5
- package/.code/agents/110/exec-call_F9BDNG7JfxKkq7Vc8ESAvdft.txt +0 -1569
- package/.code/agents/11ebcef3-b13f-4e44-ad80-d94a866804b7/error.txt +0 -3
- package/.code/agents/1398/exec-call_CjItcWMU1G6JoPshX62QvpaR.txt +0 -2832
- package/.code/agents/1398/exec-call_SUVq2ivmONQ5LMCmd7ngmOqr.txt +0 -2709
- package/.code/agents/1398/exec-call_SdNY4NOffdcC5pRYjVXHjPCK.txt +0 -2832
- package/.code/agents/1398/exec-call_qblJo9et1gsFFB63TtLOiji2.txt +0 -2832
- package/.code/agents/1398/exec-call_zaRrzlGz7GJcNzVfkAmML7Zg.txt +0 -2709
- package/.code/agents/171834fd-5905-42fc-bbcc-2c755145b0fc/status.txt +0 -1
- package/.code/agents/1724/exec-call_HvHQe0w5CCG3T7Q3ULT6MO3g.txt +0 -5217
- package/.code/agents/1724/exec-call_QwUNESVzfxxk78K1frh1Vahb.txt +0 -2594
- package/.code/agents/1724/exec-call_aJ1Xwz71XmIpD4SBxSHERzLe.txt +0 -2594
- package/.code/agents/1d7d7ab7-7473-4b69-8b97-6e914f56056a/result.txt +0 -231
- package/.code/agents/210/exec-call_0tQCsKNJ1WTuIchb8wlcFJpW.txt +0 -2590
- package/.code/agents/210/exec-call_8ZlY9cUc8Ft1twi4ch8UJ6IN.txt +0 -5195
- package/.code/agents/2188/exec-call_5HqayBxIteJtoI8oPTiLWgvJ.txt +0 -286
- package/.code/agents/2188/exec-call_XRbBKBq3adZe6dcppAvQtM7G.txt +0 -218
- package/.code/agents/2188/exec-call_ehA0SjpYtrUi6GJXmibLjp4i.txt +0 -180
- package/.code/agents/21902821-ecaf-4759-bb9d-222b90921af5/error.txt +0 -3
- package/.code/agents/232073be-aa0e-46da-b478-5b64dbf03cf5/status.txt +0 -1
- package/.code/agents/234ff534-2336-4771-a8d9-aa04421a63be/result.txt +0 -747
- package/.code/agents/253e2695-dc36-4022-b436-27655e0fc6c7/status.txt +0 -1
- package/.code/agents/2583/exec-call_M59I4eDjpjlBIWBiSxyS0YlJ.txt +0 -2594
- package/.code/agents/2583/exec-call_usLRGh7OhVHtsRBL4iUwRhjq.txt +0 -2594
- package/.code/agents/292aa3ff-dbab-470f-97c9-e7e8fd65e0db/result.txt +0 -144
- package/.code/agents/3134/exec-call_IgCAMGx19lWfuo8zfYIt5FFC.txt +0 -416
- package/.code/agents/3134/exec-call_IxvLR2Oo7kba2QTsI1gHVko8.txt +0 -2590
- package/.code/agents/3134/exec-call_jYvc8hksZChSiysbzKjl2ZbB.txt +0 -2590
- package/.code/agents/329/exec-call_4QdP3SfSO7HGPCwVcqZIth6s.txt +0 -2590
- package/.code/agents/472/exec-call_4AxzEEcWwkKhpqRB3bE8Ha4L.txt +0 -790
- package/.code/agents/472/exec-call_CB3LPYQA8QIZRi8I6kj4J17A.txt +0 -766
- package/.code/agents/472/exec-call_YeoUWvaFoktay2nqVUsa9KKX.txt +0 -790
- package/.code/agents/472/exec-call_jPWgKVquBBXTg0T3Lks5ZfkK.txt +0 -2594
- package/.code/agents/472/exec-call_qBkvunpGBDEHph2jPmTwtcsb.txt +0 -1000
- package/.code/agents/472/exec-call_v0ffRV1p0kTckBmJPzzHAEy0.txt +0 -3489
- package/.code/agents/472/exec-call_xAX5FXqWIlk02d9WubHbHWh8.txt +0 -766
- package/.code/agents/5346/exec-call_9q0muXUuLaucwEqI51Pt7idT.txt +0 -2594
- package/.code/agents/5346/exec-call_B2el3B79rVkq9LhWTI2VYlz7.txt +0 -2456
- package/.code/agents/5346/exec-call_BfX08f02qkZI9uJD5dvCvuoj.txt +0 -2594
- package/.code/agents/543328d0-61d6-4fd1-a723-bb168656e2e2/error.txt +0 -18
- package/.code/agents/5580c02c-1383-4d18-9cbd-cc8a06e3408d/result.txt +0 -48
- package/.code/agents/60ce1a22-5126-44b2-b977-1d5b56142a7b/status.txt +0 -1
- package/.code/agents/6215d9db-7fa9-4429-aeec-3835c3212291/error.txt +0 -1
- package/.code/agents/6743db55-30e5-4b4e-9366-a8214fc7f714/error.txt +0 -1
- package/.code/agents/6bf9591b-b9c9-422c-b0a5-e968c7d8422a/status.txt +0 -1
- package/.code/agents/7/exec-call_eww3GfdEiJZx61sJEQ9wNmt3.txt +0 -1271
- package/.code/agents/70/exec-call_owUtDMYiVgqDf8vsz1i32PFf.txt +0 -1570
- package/.code/agents/8/exec-call_UtrjAcLbhYLatxR4O97fZgnm.txt +0 -2590
- package/.code/agents/82490bc9-f34e-4b1b-8a8e-bccc2e6254f5/error.txt +0 -3
- package/.code/agents/841/exec-call_7nTNhSBCNjTDUIJv7py6CepO.txt +0 -3299
- package/.code/agents/841/exec-call_TLI0yUdUijuUAvI4o3DXEvHO.txt +0 -3299
- package/.code/agents/9/exec-call_XaABQT1hIlRpnKZ2uyBMWsTC.txt +0 -1882
- package/.code/agents/941/exec-call_GuGHRx7NNXWIDAnxUG2NEWPa.txt +0 -2594
- package/.code/agents/95d9fbab-19a2-48af-83f9-c792566a347f/error.txt +0 -1
- package/.code/agents/b0098cb8-cb32-4ada-9bc4-37c587518896/result.txt +0 -170
- package/.code/agents/b4fe59a4-81df-42e2-a112-0153e504faca/error.txt +0 -1
- package/.code/agents/bf4ce152-f623-49d7-aa52-c18631625c3c/error.txt +0 -3
- package/.code/agents/d7d1db75-d7eb-468e-adea-4ef4d916d187/status.txt +0 -1
- package/.code/agents/e2baa9c8-bac3-49e3-a39d-024333e6a990/status.txt +0 -1
- package/.code/agents/e350b8c3-8483-408c-b2bb-94515f492a11/error.txt +0 -3
- package/.code/agents/e63f9919-719f-4ad0-bccf-01b1a596e1e9/status.txt +0 -1
- package/.code/agents/e71695a8-3044-478d-8f12-ed13d02884c7/status.txt +0 -1
- package/.code/agents/f95b7464-3e25-4897-b153-c8dfd63fd605/error.txt +0 -5
- package/.code/agents/fa3c5ddf-cdf7-47a2-930a-b806c6363689/status.txt +0 -1
- package/.github/workflows/pr-description-check.yml +0 -88
- package/AGENTS.md +0 -36
- package/NUL +0 -1
- package/docs/README.md +0 -72
- package/docs/getting-started/CONFIGURATION.md +0 -175
- package/docs/getting-started/INSTALLATION.md +0 -333
- package/docs/getting-started/QUICKSTART.md +0 -282
- package/docs/guides/ARCHITECTURE.md +0 -533
- package/docs/guides/DEPLOYMENT.md +0 -189
- package/docs/guides/INTEGRATION_TESTING.md +0 -730
- package/docs/guides/TESTING.md +0 -591
- package/docs/reconciliation-flow.md +0 -83
- package/docs/reference/EXAMPLES.md +0 -946
- package/docs/reference/TOOLS.md +0 -348
- package/docs/reference/TROUBLESHOOTING.md +0 -481
- package/package.json.tmp +0 -105
- package/temp-recon.ts +0 -126
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +0 -23
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +0 -23
- package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +0 -44
- package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +0 -58
- package/test-exports/ynab_since_2025-10-16_account_53298e13_238items_2025-11-28_13-46-20.json +0 -3662
- package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +0 -115
|
@@ -10,6 +10,9 @@ import type { DeltaCache } from '../server/deltaCache.js';
|
|
|
10
10
|
import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
|
|
11
11
|
import { CacheKeys } from '../server/cacheKeys.js';
|
|
12
12
|
import { resolveDeltaFetcherArgs, resolveDeltaWriteArgs } from './deltaSupport.js';
|
|
13
|
+
import type { ToolFactory } from '../types/toolRegistration.js';
|
|
14
|
+
import { createAdapters, createBudgetResolver } from './adapters.js';
|
|
15
|
+
import { ToolAnnotationPresets } from './toolCategories.js';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* Schema for ynab:list_accounts tool parameters
|
|
@@ -286,3 +289,53 @@ export async function handleCreateAccount(
|
|
|
286
289
|
'creating account',
|
|
287
290
|
);
|
|
288
291
|
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Registers all account-related tools with the registry.
|
|
295
|
+
*/
|
|
296
|
+
export const registerAccountTools: ToolFactory = (registry, context) => {
|
|
297
|
+
const { adapt, adaptWithDelta, adaptWrite } = createAdapters(context);
|
|
298
|
+
const budgetResolver = createBudgetResolver(context);
|
|
299
|
+
|
|
300
|
+
registry.register({
|
|
301
|
+
name: 'list_accounts',
|
|
302
|
+
description: 'List all accounts for a specific budget',
|
|
303
|
+
inputSchema: ListAccountsSchema,
|
|
304
|
+
handler: adaptWithDelta(handleListAccounts),
|
|
305
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof ListAccountsSchema>>(),
|
|
306
|
+
metadata: {
|
|
307
|
+
annotations: {
|
|
308
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
309
|
+
title: 'YNAB: List Accounts',
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
registry.register({
|
|
315
|
+
name: 'get_account',
|
|
316
|
+
description: 'Get detailed information for a specific account',
|
|
317
|
+
inputSchema: GetAccountSchema,
|
|
318
|
+
handler: adapt(handleGetAccount),
|
|
319
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof GetAccountSchema>>(),
|
|
320
|
+
metadata: {
|
|
321
|
+
annotations: {
|
|
322
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
323
|
+
title: 'YNAB: Get Account Details',
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
registry.register({
|
|
329
|
+
name: 'create_account',
|
|
330
|
+
description: 'Create a new account in the specified budget',
|
|
331
|
+
inputSchema: CreateAccountSchema,
|
|
332
|
+
handler: adaptWrite(handleCreateAccount),
|
|
333
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof CreateAccountSchema>>(),
|
|
334
|
+
metadata: {
|
|
335
|
+
annotations: {
|
|
336
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
|
|
337
|
+
title: 'YNAB: Create Account',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Adapter utilities for tool factory functions.
|
|
3
|
+
* Provides createAdapters() to reduce boilerplate when registering tools,
|
|
4
|
+
* and createBudgetResolver() for consistent budget ID resolution.
|
|
5
|
+
* @module tools/adapters
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
import type { ToolExecutionPayload, DefaultArgumentResolver } from '../server/toolRegistry.js';
|
|
10
|
+
import { BudgetResolver } from '../server/budgetResolver.js';
|
|
11
|
+
import { DefaultArgumentResolutionError } from '../server/toolRegistry.js';
|
|
12
|
+
import type {
|
|
13
|
+
ToolContext,
|
|
14
|
+
Handler,
|
|
15
|
+
DeltaHandler,
|
|
16
|
+
WriteHandler,
|
|
17
|
+
NoInputHandler,
|
|
18
|
+
} from '../types/toolRegistration.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates adapter functions bound to the provided context. These helpers reduce
|
|
22
|
+
* boilerplate inside tool factory modules by partially applying shared
|
|
23
|
+
* dependencies to handlers.
|
|
24
|
+
*/
|
|
25
|
+
export function createAdapters(context: ToolContext) {
|
|
26
|
+
const { ynabAPI, deltaFetcher, deltaCache, serverKnowledgeStore } = context;
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
adapt:
|
|
30
|
+
<TInput extends Record<string, unknown>>(handler: Handler<TInput>) =>
|
|
31
|
+
async ({ input }: ToolExecutionPayload<TInput>): Promise<CallToolResult> =>
|
|
32
|
+
handler(ynabAPI, input),
|
|
33
|
+
|
|
34
|
+
adaptNoInput:
|
|
35
|
+
(handler: NoInputHandler) =>
|
|
36
|
+
async (_payload: ToolExecutionPayload<Record<string, unknown>>): Promise<CallToolResult> =>
|
|
37
|
+
handler(ynabAPI),
|
|
38
|
+
|
|
39
|
+
adaptWithDelta:
|
|
40
|
+
<TInput extends Record<string, unknown>>(handler: DeltaHandler<TInput>) =>
|
|
41
|
+
async ({ input }: ToolExecutionPayload<TInput>): Promise<CallToolResult> =>
|
|
42
|
+
handler(ynabAPI, deltaFetcher, input),
|
|
43
|
+
|
|
44
|
+
adaptWrite:
|
|
45
|
+
<TInput extends Record<string, unknown>>(handler: WriteHandler<TInput>) =>
|
|
46
|
+
async ({ input }: ToolExecutionPayload<TInput>): Promise<CallToolResult> =>
|
|
47
|
+
handler(ynabAPI, deltaCache, serverKnowledgeStore, input),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Creates a budget ID resolver bound to the provided context. The returned
|
|
53
|
+
* resolver matches the ToolRegistry defaultArgumentResolver signature.
|
|
54
|
+
*/
|
|
55
|
+
export function createBudgetResolver(
|
|
56
|
+
context: ToolContext,
|
|
57
|
+
): <TInput extends { budget_id?: string | undefined }>() => DefaultArgumentResolver<TInput> {
|
|
58
|
+
return <TInput extends { budget_id?: string | undefined }>(): DefaultArgumentResolver<TInput> => {
|
|
59
|
+
return ({ rawArguments }) => {
|
|
60
|
+
const provided =
|
|
61
|
+
typeof rawArguments['budget_id'] === 'string' && rawArguments['budget_id'].length > 0
|
|
62
|
+
? rawArguments['budget_id']
|
|
63
|
+
: undefined;
|
|
64
|
+
|
|
65
|
+
const result = BudgetResolver.resolveBudgetId(provided, context.getDefaultBudgetId());
|
|
66
|
+
|
|
67
|
+
if (typeof result === 'string') {
|
|
68
|
+
return { budget_id: result } as Partial<TInput>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
throw new DefaultArgumentResolutionError(result);
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|
package/src/tools/budgetTools.ts
CHANGED
|
@@ -5,6 +5,10 @@ import { withToolErrorHandling } from '../types/index.js';
|
|
|
5
5
|
import { responseFormatter } from '../server/responseFormatter.js';
|
|
6
6
|
import type { DeltaFetcher } from './deltaFetcher.js';
|
|
7
7
|
import { resolveDeltaFetcherArgs } from './deltaSupport.js';
|
|
8
|
+
import type { ToolFactory } from '../types/toolRegistration.js';
|
|
9
|
+
import { createAdapters } from './adapters.js';
|
|
10
|
+
import { ToolAnnotationPresets } from './toolCategories.js';
|
|
11
|
+
import { emptyObjectSchema } from './schemas/common.js';
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* Schema for ynab:get_budget tool parameters
|
|
@@ -110,3 +114,36 @@ export async function handleGetBudget(
|
|
|
110
114
|
'getting budget details',
|
|
111
115
|
);
|
|
112
116
|
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Registers all budget-related tools with the provided registry.
|
|
120
|
+
*/
|
|
121
|
+
export const registerBudgetTools: ToolFactory = (registry, context) => {
|
|
122
|
+
const { adapt, adaptWithDelta } = createAdapters(context);
|
|
123
|
+
|
|
124
|
+
registry.register({
|
|
125
|
+
name: 'list_budgets',
|
|
126
|
+
description: "List all budgets associated with the user's account",
|
|
127
|
+
inputSchema: emptyObjectSchema,
|
|
128
|
+
handler: adaptWithDelta(handleListBudgets),
|
|
129
|
+
metadata: {
|
|
130
|
+
annotations: {
|
|
131
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
132
|
+
title: 'YNAB: List Budgets',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
registry.register({
|
|
138
|
+
name: 'get_budget',
|
|
139
|
+
description: 'Get detailed information for a specific budget',
|
|
140
|
+
inputSchema: GetBudgetSchema,
|
|
141
|
+
handler: adapt(handleGetBudget),
|
|
142
|
+
metadata: {
|
|
143
|
+
annotations: {
|
|
144
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
145
|
+
title: 'YNAB: Get Budget Details',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
};
|
|
@@ -10,6 +10,9 @@ import type { DeltaCache } from '../server/deltaCache.js';
|
|
|
10
10
|
import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
|
|
11
11
|
import { CacheKeys } from '../server/cacheKeys.js';
|
|
12
12
|
import { resolveDeltaFetcherArgs, resolveDeltaWriteArgs } from './deltaSupport.js';
|
|
13
|
+
import type { ToolFactory } from '../types/toolRegistration.js';
|
|
14
|
+
import { createAdapters, createBudgetResolver } from './adapters.js';
|
|
15
|
+
import { ToolAnnotationPresets } from './toolCategories.js';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* Schema for ynab:list_categories tool parameters
|
|
@@ -336,6 +339,56 @@ export async function handleUpdateCategory(
|
|
|
336
339
|
}
|
|
337
340
|
}
|
|
338
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Registers all category-related tools with the registry.
|
|
344
|
+
*/
|
|
345
|
+
export const registerCategoryTools: ToolFactory = (registry, context) => {
|
|
346
|
+
const { adapt, adaptWithDelta, adaptWrite } = createAdapters(context);
|
|
347
|
+
const budgetResolver = createBudgetResolver(context);
|
|
348
|
+
|
|
349
|
+
registry.register({
|
|
350
|
+
name: 'list_categories',
|
|
351
|
+
description: 'List all categories for a specific budget',
|
|
352
|
+
inputSchema: ListCategoriesSchema,
|
|
353
|
+
handler: adaptWithDelta(handleListCategories),
|
|
354
|
+
defaultArgumentResolver: budgetResolver<ListCategoriesParams>(),
|
|
355
|
+
metadata: {
|
|
356
|
+
annotations: {
|
|
357
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
358
|
+
title: 'YNAB: List Categories',
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
registry.register({
|
|
364
|
+
name: 'get_category',
|
|
365
|
+
description: 'Get detailed information for a specific category',
|
|
366
|
+
inputSchema: GetCategorySchema,
|
|
367
|
+
handler: adapt(handleGetCategory),
|
|
368
|
+
defaultArgumentResolver: budgetResolver<GetCategoryParams>(),
|
|
369
|
+
metadata: {
|
|
370
|
+
annotations: {
|
|
371
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
372
|
+
title: 'YNAB: Get Category Details',
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
registry.register({
|
|
378
|
+
name: 'update_category',
|
|
379
|
+
description: 'Update the budgeted amount for a category in the current month',
|
|
380
|
+
inputSchema: UpdateCategorySchema,
|
|
381
|
+
handler: adaptWrite(handleUpdateCategory),
|
|
382
|
+
defaultArgumentResolver: budgetResolver<UpdateCategoryParams>(),
|
|
383
|
+
metadata: {
|
|
384
|
+
annotations: {
|
|
385
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
|
|
386
|
+
title: 'YNAB: Update Category Budget',
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
};
|
|
391
|
+
|
|
339
392
|
/**
|
|
340
393
|
* Handles errors from category-related API calls
|
|
341
394
|
*/
|
package/src/tools/monthTools.ts
CHANGED
|
@@ -8,6 +8,9 @@ import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.j
|
|
|
8
8
|
import type { DeltaFetcher } from './deltaFetcher.js';
|
|
9
9
|
import { CacheKeys } from '../server/cacheKeys.js';
|
|
10
10
|
import { resolveDeltaFetcherArgs } from './deltaSupport.js';
|
|
11
|
+
import type { ToolFactory } from '../types/toolRegistration.js';
|
|
12
|
+
import { createAdapters, createBudgetResolver } from './adapters.js';
|
|
13
|
+
import { ToolAnnotationPresets } from './toolCategories.js';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* Schema for ynab:get_month tool parameters
|
|
@@ -168,3 +171,39 @@ export async function handleListMonths(
|
|
|
168
171
|
'listing months',
|
|
169
172
|
);
|
|
170
173
|
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Registers all month-related tools with the registry.
|
|
177
|
+
*/
|
|
178
|
+
export const registerMonthTools: ToolFactory = (registry, context) => {
|
|
179
|
+
const { adapt, adaptWithDelta } = createAdapters(context);
|
|
180
|
+
const budgetResolver = createBudgetResolver(context);
|
|
181
|
+
|
|
182
|
+
registry.register({
|
|
183
|
+
name: 'get_month',
|
|
184
|
+
description: 'Get budget data for a specific month',
|
|
185
|
+
inputSchema: GetMonthSchema,
|
|
186
|
+
handler: adapt(handleGetMonth),
|
|
187
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof GetMonthSchema>>(),
|
|
188
|
+
metadata: {
|
|
189
|
+
annotations: {
|
|
190
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
191
|
+
title: 'YNAB: Get Month Details',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
registry.register({
|
|
197
|
+
name: 'list_months',
|
|
198
|
+
description: 'List all months summary data for a budget',
|
|
199
|
+
inputSchema: ListMonthsSchema,
|
|
200
|
+
handler: adaptWithDelta(handleListMonths),
|
|
201
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof ListMonthsSchema>>(),
|
|
202
|
+
metadata: {
|
|
203
|
+
annotations: {
|
|
204
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
205
|
+
title: 'YNAB: List Months',
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
};
|
package/src/tools/payeeTools.ts
CHANGED
|
@@ -7,6 +7,9 @@ import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.j
|
|
|
7
7
|
import type { DeltaFetcher } from './deltaFetcher.js';
|
|
8
8
|
import { CacheKeys } from '../server/cacheKeys.js';
|
|
9
9
|
import { resolveDeltaFetcherArgs } from './deltaSupport.js';
|
|
10
|
+
import type { ToolFactory } from '../types/toolRegistration.js';
|
|
11
|
+
import { createAdapters, createBudgetResolver } from './adapters.js';
|
|
12
|
+
import { ToolAnnotationPresets } from './toolCategories.js';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Schema for ynab:list_payees tool parameters
|
|
@@ -144,3 +147,39 @@ export async function handleGetPayee(
|
|
|
144
147
|
'getting payee details',
|
|
145
148
|
);
|
|
146
149
|
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Registers all payee-related tools with the registry.
|
|
153
|
+
*/
|
|
154
|
+
export const registerPayeeTools: ToolFactory = (registry, context) => {
|
|
155
|
+
const { adapt, adaptWithDelta } = createAdapters(context);
|
|
156
|
+
const budgetResolver = createBudgetResolver(context);
|
|
157
|
+
|
|
158
|
+
registry.register({
|
|
159
|
+
name: 'list_payees',
|
|
160
|
+
description: 'List all payees for a specific budget',
|
|
161
|
+
inputSchema: ListPayeesSchema,
|
|
162
|
+
handler: adaptWithDelta(handleListPayees),
|
|
163
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof ListPayeesSchema>>(),
|
|
164
|
+
metadata: {
|
|
165
|
+
annotations: {
|
|
166
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
167
|
+
title: 'YNAB: List Payees',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
registry.register({
|
|
173
|
+
name: 'get_payee',
|
|
174
|
+
description: 'Get detailed information for a specific payee',
|
|
175
|
+
inputSchema: GetPayeeSchema,
|
|
176
|
+
handler: adapt(handleGetPayee),
|
|
177
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof GetPayeeSchema>>(),
|
|
178
|
+
metadata: {
|
|
179
|
+
annotations: {
|
|
180
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
181
|
+
title: 'YNAB: Get Payee Details',
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
};
|
|
@@ -8,6 +8,13 @@ import { z } from 'zod/v4';
|
|
|
8
8
|
import type * as ynab from 'ynab';
|
|
9
9
|
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
10
10
|
import { withToolErrorHandling } from '../../types/index.js';
|
|
11
|
+
import type { ToolFactory } from '../../types/toolRegistration.js';
|
|
12
|
+
import { createAdapters, createBudgetResolver } from '../adapters.js';
|
|
13
|
+
import { ToolAnnotationPresets } from '../toolCategories.js';
|
|
14
|
+
import {
|
|
15
|
+
CompareTransactionsSchema,
|
|
16
|
+
handleCompareTransactions,
|
|
17
|
+
} from '../compareTransactions/index.js';
|
|
11
18
|
import { analyzeReconciliation } from './analyzer.js';
|
|
12
19
|
import type { MatchingConfig } from './matcher.js';
|
|
13
20
|
import { buildReconciliationPayload } from '../reconcileAdapter.js';
|
|
@@ -457,6 +464,44 @@ export async function handleReconcileAccount(
|
|
|
457
464
|
);
|
|
458
465
|
}
|
|
459
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Registers reconciliation-domain tools (compare + reconcile) with the registry.
|
|
469
|
+
*/
|
|
470
|
+
export const registerReconciliationTools: ToolFactory = (registry, context) => {
|
|
471
|
+
const { adapt, adaptWithDelta } = createAdapters(context);
|
|
472
|
+
const budgetResolver = createBudgetResolver(context);
|
|
473
|
+
|
|
474
|
+
registry.register({
|
|
475
|
+
name: 'compare_transactions',
|
|
476
|
+
description:
|
|
477
|
+
'Compare bank transactions from CSV with YNAB transactions to find missing entries',
|
|
478
|
+
inputSchema: CompareTransactionsSchema,
|
|
479
|
+
handler: adapt(handleCompareTransactions),
|
|
480
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof CompareTransactionsSchema>>(),
|
|
481
|
+
metadata: {
|
|
482
|
+
annotations: {
|
|
483
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
484
|
+
title: 'YNAB: Compare Transactions',
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
registry.register({
|
|
490
|
+
name: 'reconcile_account',
|
|
491
|
+
description:
|
|
492
|
+
'Guided reconciliation workflow with human narrative, insight detection, and optional execution (create/update/unclear). Set include_structured_data=true to also get full JSON output (large).',
|
|
493
|
+
inputSchema: ReconcileAccountSchema,
|
|
494
|
+
handler: adaptWithDelta(handleReconcileAccount),
|
|
495
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof ReconcileAccountSchema>>(),
|
|
496
|
+
metadata: {
|
|
497
|
+
annotations: {
|
|
498
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
|
|
499
|
+
title: 'YNAB: Reconcile Account',
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
};
|
|
504
|
+
|
|
460
505
|
function mapCsvDateFormatToHint(
|
|
461
506
|
format: string | undefined,
|
|
462
507
|
): ParseCSVOptions['dateFormat'] | undefined {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared Zod schemas used across multiple tool domains.
|
|
3
|
+
* @module tools/schemas/common
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod/v4';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Strict empty object schema used for tools that do not accept input params.
|
|
10
|
+
* Examples: list_budgets, get_user, get_default_budget, clear_cache
|
|
11
|
+
*/
|
|
12
|
+
export const emptyObjectSchema = z.object({}).strict();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Permissive object schema used when hosts require a top-level object but we
|
|
16
|
+
* intentionally allow passthrough properties (e.g., mutation tool outputs).
|
|
17
|
+
*/
|
|
18
|
+
export const looseObjectSchema = z.object({}).passthrough();
|
|
@@ -25,8 +25,6 @@
|
|
|
25
25
|
export {
|
|
26
26
|
GetUserOutputSchema,
|
|
27
27
|
type GetUserOutput,
|
|
28
|
-
ConvertAmountOutputSchema,
|
|
29
|
-
type ConvertAmountOutput,
|
|
30
28
|
GetDefaultBudgetOutputSchema,
|
|
31
29
|
type GetDefaultBudgetOutput,
|
|
32
30
|
SetDefaultBudgetOutputSchema,
|
|
@@ -44,7 +42,6 @@ export {
|
|
|
44
42
|
// Nested schemas that may be useful independently
|
|
45
43
|
export {
|
|
46
44
|
UserSchema,
|
|
47
|
-
ConversionSchema,
|
|
48
45
|
DateFormatSchema,
|
|
49
46
|
CurrencyFormatSchema,
|
|
50
47
|
BudgetDetailSchema,
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @fileoverview Output schemas for utility tools
|
|
3
3
|
*
|
|
4
4
|
* This file contains comprehensive Zod schemas for validating the output
|
|
5
|
-
* of utility tools including user info,
|
|
6
|
-
*
|
|
5
|
+
* of utility tools including user info, budget defaults, cache management,
|
|
6
|
+
* output formatting, and diagnostic information.
|
|
7
7
|
*
|
|
8
8
|
* All schemas include TypeScript type inference for type-safe usage throughout
|
|
9
9
|
* the codebase. Reference the corresponding handler implementations for
|
|
@@ -46,47 +46,6 @@ export const GetUserOutputSchema = z.object({
|
|
|
46
46
|
|
|
47
47
|
export type GetUserOutput = z.infer<typeof GetUserOutputSchema>;
|
|
48
48
|
|
|
49
|
-
// ============================================================================
|
|
50
|
-
// CONVERT AMOUNT OUTPUT
|
|
51
|
-
// ============================================================================
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Schema for amount conversion details
|
|
55
|
-
*
|
|
56
|
-
* Contains the conversion result between dollars and YNAB milliunits.
|
|
57
|
-
*/
|
|
58
|
-
export const ConversionSchema = z.object({
|
|
59
|
-
original_amount: z.number(),
|
|
60
|
-
converted_amount: z.number(),
|
|
61
|
-
to_milliunits: z.boolean(),
|
|
62
|
-
description: z.string(),
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Output schema for convert_amount tool
|
|
67
|
-
*
|
|
68
|
-
* Converts between dollars and YNAB milliunits (1 dollar = 1000 milliunits).
|
|
69
|
-
*
|
|
70
|
-
* @see src/tools/utilityTools.ts:51-90 - Handler implementation
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* ```typescript
|
|
74
|
-
* const output: ConvertAmountOutput = {
|
|
75
|
-
* conversion: {
|
|
76
|
-
* original_amount: 25.50,
|
|
77
|
-
* converted_amount: 25500,
|
|
78
|
-
* to_milliunits: true,
|
|
79
|
-
* description: "$25.50 converted to 25500 milliunits"
|
|
80
|
-
* }
|
|
81
|
-
* };
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
export const ConvertAmountOutputSchema = z.object({
|
|
85
|
-
conversion: ConversionSchema,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
export type ConvertAmountOutput = z.infer<typeof ConvertAmountOutputSchema>;
|
|
89
|
-
|
|
90
49
|
// ============================================================================
|
|
91
50
|
// GET DEFAULT BUDGET OUTPUT
|
|
92
51
|
// ============================================================================
|
|
@@ -120,7 +120,6 @@ export const ToolAnnotationPresets = {
|
|
|
120
120
|
* interacting with the YNAB API.
|
|
121
121
|
*
|
|
122
122
|
* Examples:
|
|
123
|
-
* - convert_amount: Converts between dollars and milliunits
|
|
124
123
|
* - set_output_format: Configures local output formatting
|
|
125
124
|
* - diagnostic_info: Returns local server diagnostic information
|
|
126
125
|
* - clear_cache: Clears local in-memory cache
|
|
@@ -6,6 +6,9 @@ import type { SaveTransactionsResponseData } from 'ynab/dist/models/SaveTransact
|
|
|
6
6
|
import { z } from 'zod/v4';
|
|
7
7
|
import { createHash } from 'crypto';
|
|
8
8
|
import { ValidationError, withToolErrorHandling } from '../types/index.js';
|
|
9
|
+
import type { ToolFactory } from '../types/toolRegistration.js';
|
|
10
|
+
import { createAdapters, createBudgetResolver } from './adapters.js';
|
|
11
|
+
import { ToolAnnotationPresets } from './toolCategories.js';
|
|
9
12
|
import { responseFormatter } from '../server/responseFormatter.js';
|
|
10
13
|
import { amountToMilliunits, milliunitsToAmount } from '../utils/amountUtils.js';
|
|
11
14
|
import { cacheManager, CACHE_TTLS, CacheManager } from '../server/cacheManager.js';
|
|
@@ -14,6 +17,7 @@ import type { DeltaFetcher } from './deltaFetcher.js';
|
|
|
14
17
|
import type { DeltaCache } from '../server/deltaCache.js';
|
|
15
18
|
import type { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
|
|
16
19
|
import { resolveDeltaFetcherArgs, resolveDeltaWriteArgs } from './deltaSupport.js';
|
|
20
|
+
import { handleExportTransactions, ExportTransactionsSchema } from './exportTransactions.js';
|
|
17
21
|
|
|
18
22
|
/**
|
|
19
23
|
* Utility function to ensure transaction is not null/undefined
|
|
@@ -2506,3 +2510,139 @@ function handleTransactionError(error: unknown, defaultMessage: string): CallToo
|
|
|
2506
2510
|
],
|
|
2507
2511
|
};
|
|
2508
2512
|
}
|
|
2513
|
+
|
|
2514
|
+
/**
|
|
2515
|
+
* Registers transaction-domain tools with the provided registry.
|
|
2516
|
+
*/
|
|
2517
|
+
export const registerTransactionTools: ToolFactory = (registry, context) => {
|
|
2518
|
+
const { adapt, adaptWithDelta, adaptWrite } = createAdapters(context);
|
|
2519
|
+
const budgetResolver = createBudgetResolver(context);
|
|
2520
|
+
|
|
2521
|
+
registry.register({
|
|
2522
|
+
name: 'list_transactions',
|
|
2523
|
+
description: 'List transactions for a budget with optional filtering',
|
|
2524
|
+
inputSchema: ListTransactionsSchema,
|
|
2525
|
+
handler: adaptWithDelta(handleListTransactions),
|
|
2526
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof ListTransactionsSchema>>(),
|
|
2527
|
+
metadata: {
|
|
2528
|
+
annotations: {
|
|
2529
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
2530
|
+
title: 'YNAB: List Transactions',
|
|
2531
|
+
},
|
|
2532
|
+
},
|
|
2533
|
+
});
|
|
2534
|
+
|
|
2535
|
+
registry.register({
|
|
2536
|
+
name: 'export_transactions',
|
|
2537
|
+
description: 'Export all transactions to a JSON file with descriptive filename',
|
|
2538
|
+
inputSchema: ExportTransactionsSchema,
|
|
2539
|
+
handler: adapt(handleExportTransactions),
|
|
2540
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof ExportTransactionsSchema>>(),
|
|
2541
|
+
metadata: {
|
|
2542
|
+
annotations: {
|
|
2543
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
2544
|
+
title: 'YNAB: Export Transactions',
|
|
2545
|
+
},
|
|
2546
|
+
},
|
|
2547
|
+
});
|
|
2548
|
+
|
|
2549
|
+
registry.register({
|
|
2550
|
+
name: 'get_transaction',
|
|
2551
|
+
description: 'Get detailed information for a specific transaction',
|
|
2552
|
+
inputSchema: GetTransactionSchema,
|
|
2553
|
+
handler: adapt(handleGetTransaction),
|
|
2554
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof GetTransactionSchema>>(),
|
|
2555
|
+
metadata: {
|
|
2556
|
+
annotations: {
|
|
2557
|
+
...ToolAnnotationPresets.READ_ONLY_EXTERNAL,
|
|
2558
|
+
title: 'YNAB: Get Transaction Details',
|
|
2559
|
+
},
|
|
2560
|
+
},
|
|
2561
|
+
});
|
|
2562
|
+
|
|
2563
|
+
registry.register({
|
|
2564
|
+
name: 'create_transaction',
|
|
2565
|
+
description: 'Create a new transaction in the specified budget and account',
|
|
2566
|
+
inputSchema: CreateTransactionSchema,
|
|
2567
|
+
handler: adaptWrite(handleCreateTransaction),
|
|
2568
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof CreateTransactionSchema>>(),
|
|
2569
|
+
metadata: {
|
|
2570
|
+
annotations: {
|
|
2571
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
|
|
2572
|
+
title: 'YNAB: Create Transaction',
|
|
2573
|
+
},
|
|
2574
|
+
},
|
|
2575
|
+
});
|
|
2576
|
+
|
|
2577
|
+
registry.register({
|
|
2578
|
+
name: 'create_transactions',
|
|
2579
|
+
description:
|
|
2580
|
+
'Create multiple transactions in a single batch (1-100 items) with duplicate detection, dry-run validation, and automatic response size management with correlation metadata.',
|
|
2581
|
+
inputSchema: CreateTransactionsSchema,
|
|
2582
|
+
handler: adaptWrite(handleCreateTransactions),
|
|
2583
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof CreateTransactionsSchema>>(),
|
|
2584
|
+
metadata: {
|
|
2585
|
+
annotations: {
|
|
2586
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
|
|
2587
|
+
title: 'YNAB: Create Multiple Transactions',
|
|
2588
|
+
},
|
|
2589
|
+
},
|
|
2590
|
+
});
|
|
2591
|
+
|
|
2592
|
+
registry.register({
|
|
2593
|
+
name: 'create_receipt_split_transaction',
|
|
2594
|
+
description: 'Create a split transaction from receipt items with proportional tax allocation',
|
|
2595
|
+
inputSchema: CreateReceiptSplitTransactionSchema,
|
|
2596
|
+
handler: adaptWrite(handleCreateReceiptSplitTransaction),
|
|
2597
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof CreateReceiptSplitTransactionSchema>>(),
|
|
2598
|
+
metadata: {
|
|
2599
|
+
annotations: {
|
|
2600
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_CREATE,
|
|
2601
|
+
title: 'YNAB: Create Split Transaction from Receipt',
|
|
2602
|
+
},
|
|
2603
|
+
},
|
|
2604
|
+
});
|
|
2605
|
+
|
|
2606
|
+
registry.register({
|
|
2607
|
+
name: 'update_transaction',
|
|
2608
|
+
description: 'Update an existing transaction',
|
|
2609
|
+
inputSchema: UpdateTransactionSchema,
|
|
2610
|
+
handler: adaptWrite(handleUpdateTransaction),
|
|
2611
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof UpdateTransactionSchema>>(),
|
|
2612
|
+
metadata: {
|
|
2613
|
+
annotations: {
|
|
2614
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
|
|
2615
|
+
title: 'YNAB: Update Transaction',
|
|
2616
|
+
},
|
|
2617
|
+
},
|
|
2618
|
+
});
|
|
2619
|
+
|
|
2620
|
+
registry.register({
|
|
2621
|
+
name: 'update_transactions',
|
|
2622
|
+
description:
|
|
2623
|
+
'Update multiple transactions in a single batch (1-100 items) with dry-run validation, automatic cache invalidation, and response size management. Supports optional original_account_id and original_date metadata for efficient cache invalidation.',
|
|
2624
|
+
inputSchema: UpdateTransactionsSchema,
|
|
2625
|
+
handler: adaptWrite(handleUpdateTransactions),
|
|
2626
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof UpdateTransactionsSchema>>(),
|
|
2627
|
+
metadata: {
|
|
2628
|
+
annotations: {
|
|
2629
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_UPDATE,
|
|
2630
|
+
title: 'YNAB: Update Multiple Transactions',
|
|
2631
|
+
},
|
|
2632
|
+
},
|
|
2633
|
+
});
|
|
2634
|
+
|
|
2635
|
+
registry.register({
|
|
2636
|
+
name: 'delete_transaction',
|
|
2637
|
+
description: 'Delete a transaction from the specified budget',
|
|
2638
|
+
inputSchema: DeleteTransactionSchema,
|
|
2639
|
+
handler: adaptWrite(handleDeleteTransaction),
|
|
2640
|
+
defaultArgumentResolver: budgetResolver<z.infer<typeof DeleteTransactionSchema>>(),
|
|
2641
|
+
metadata: {
|
|
2642
|
+
annotations: {
|
|
2643
|
+
...ToolAnnotationPresets.WRITE_EXTERNAL_DELETE,
|
|
2644
|
+
title: 'YNAB: Delete Transaction',
|
|
2645
|
+
},
|
|
2646
|
+
},
|
|
2647
|
+
});
|
|
2648
|
+
};
|