create_transactions
Insert one or more financial transactions into LunchMoney with details like date, payee, amount, currency, category, and status for expense tracking.
Instructions
Insert one or more transactions
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes |
Implementation Reference
- src/tools/transactions.ts:264-313 (handler)The handler function that implements the create_transactions tool by sending a POST request to the LunchMoney API to insert transactions.
async ({ input }) => { const { baseUrl, lunchmoneyApiToken } = getConfig(); const body: any = { transactions: input.transactions, }; if (input.apply_rules !== undefined) body.apply_rules = input.apply_rules; if (input.skip_duplicates !== undefined) body.skip_duplicates = input.skip_duplicates; if (input.check_for_recurring !== undefined) body.check_for_recurring = input.check_for_recurring; if (input.debit_as_negative !== undefined) body.debit_as_negative = input.debit_as_negative; if (input.skip_balance_update !== undefined) body.skip_balance_update = input.skip_balance_update; const response = await fetch(`${baseUrl}/transactions`, { method: "POST", headers: { Authorization: `Bearer ${lunchmoneyApiToken}`, "Content-Type": "application/json", }, body: JSON.stringify(body), }); if (!response.ok) { return { content: [ { type: "text", text: `Failed to create transactions: ${response.statusText}`, }, ], }; } const result = await response.json(); return { content: [ { type: "text", text: JSON.stringify(result), }, ], }; } ); - src/tools/transactions.ts:187-262 (schema)The Zod input schema defining the parameters for creating transactions, including the array of transactions and optional flags.
transactions: z .array( z.object({ date: z .string() .describe("Date in YYYY-MM-DD format"), payee: z.string().describe("Payee name"), amount: z .string() .describe( "Amount as string with up to 4 decimal places" ), currency: z .string() .optional() .describe( "Three-letter lowercase currency code" ), category_id: z .number() .optional() .describe("Category ID"), asset_id: z .number() .optional() .describe("Asset ID for manual accounts"), recurring_id: z .number() .optional() .describe("Recurring expense ID"), notes: z .string() .optional() .describe("Transaction notes"), status: z .enum(["cleared", "uncleared", "pending"]) .optional() .describe("Transaction status"), external_id: z .string() .optional() .describe("External ID (max 75 characters)"), tags: z .array(z.number()) .optional() .describe("Array of tag IDs"), }) ) .describe("Array of transactions to create"), apply_rules: z .boolean() .optional() .describe("Apply account's rules to transactions"), skip_duplicates: z .boolean() .optional() .describe( "Skip transactions that are potential duplicates" ), check_for_recurring: z .boolean() .optional() .describe( "Check if transactions are part of recurring expenses" ), debit_as_negative: z .boolean() .optional() .describe( "Pass true if debits are provided as negative amounts" ), skip_balance_update: z .boolean() .optional() .describe("Skip updating balance for assets/accounts"), }), - src/tools/transactions.ts:182-313 (registration)The registration of the create_transactions tool using server.tool(), including name, description, schema, and handler.
server.tool( "create_transactions", "Insert one or more transactions", { input: z.object({ transactions: z .array( z.object({ date: z .string() .describe("Date in YYYY-MM-DD format"), payee: z.string().describe("Payee name"), amount: z .string() .describe( "Amount as string with up to 4 decimal places" ), currency: z .string() .optional() .describe( "Three-letter lowercase currency code" ), category_id: z .number() .optional() .describe("Category ID"), asset_id: z .number() .optional() .describe("Asset ID for manual accounts"), recurring_id: z .number() .optional() .describe("Recurring expense ID"), notes: z .string() .optional() .describe("Transaction notes"), status: z .enum(["cleared", "uncleared", "pending"]) .optional() .describe("Transaction status"), external_id: z .string() .optional() .describe("External ID (max 75 characters)"), tags: z .array(z.number()) .optional() .describe("Array of tag IDs"), }) ) .describe("Array of transactions to create"), apply_rules: z .boolean() .optional() .describe("Apply account's rules to transactions"), skip_duplicates: z .boolean() .optional() .describe( "Skip transactions that are potential duplicates" ), check_for_recurring: z .boolean() .optional() .describe( "Check if transactions are part of recurring expenses" ), debit_as_negative: z .boolean() .optional() .describe( "Pass true if debits are provided as negative amounts" ), skip_balance_update: z .boolean() .optional() .describe("Skip updating balance for assets/accounts"), }), }, async ({ input }) => { const { baseUrl, lunchmoneyApiToken } = getConfig(); const body: any = { transactions: input.transactions, }; if (input.apply_rules !== undefined) body.apply_rules = input.apply_rules; if (input.skip_duplicates !== undefined) body.skip_duplicates = input.skip_duplicates; if (input.check_for_recurring !== undefined) body.check_for_recurring = input.check_for_recurring; if (input.debit_as_negative !== undefined) body.debit_as_negative = input.debit_as_negative; if (input.skip_balance_update !== undefined) body.skip_balance_update = input.skip_balance_update; const response = await fetch(`${baseUrl}/transactions`, { method: "POST", headers: { Authorization: `Bearer ${lunchmoneyApiToken}`, "Content-Type": "application/json", }, body: JSON.stringify(body), }); if (!response.ok) { return { content: [ { type: "text", text: `Failed to create transactions: ${response.statusText}`, }, ], }; } const result = await response.json(); return { content: [ { type: "text", text: JSON.stringify(result), }, ], }; } );