Skip to main content
Glama
akutishevsky

LunchMoney MCP Server

get_transactions

Retrieve financial transactions from LunchMoney within specified date ranges using filters for tags, categories, accounts, and status to analyze spending patterns.

Instructions

Retrieve transactions within a date range with optional filters

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
inputYes

Implementation Reference

  • Handler function that constructs API parameters from input, fetches transactions from Lunchmoney API, and returns JSON response.
    async ({ input }) => { const { baseUrl, lunchmoneyApiToken } = getConfig(); const params = new URLSearchParams({ start_date: input.start_date, end_date: input.end_date, }); if (input.tag_id !== undefined) params.append("tag_id", input.tag_id.toString()); if (input.recurring_id !== undefined) params.append("recurring_id", input.recurring_id.toString()); if (input.plaid_account_id !== undefined) params.append( "plaid_account_id", input.plaid_account_id.toString() ); if (input.category_id !== undefined) params.append("category_id", input.category_id.toString()); if (input.asset_id !== undefined) params.append("asset_id", input.asset_id.toString()); if (input.is_group !== undefined) params.append("is_group", input.is_group.toString()); if (input.status !== undefined) params.append("status", input.status); if (input.offset !== undefined) params.append("offset", input.offset.toString()); if (input.limit !== undefined) params.append("limit", input.limit.toString()); if (input.debit_as_negative !== undefined) params.append( "debit_as_negative", input.debit_as_negative.toString() ); const response = await fetch(`${baseUrl}/transactions?${params}`, { headers: { Authorization: `Bearer ${lunchmoneyApiToken}`, }, }); if (!response.ok) { return { content: [ { type: "text", text: `Failed to get transactions: ${response.statusText}`, }, ], }; } const data = await response.json(); const transactions: Transaction[] = data.transactions; return { content: [ { type: "text", text: JSON.stringify({ transactions, has_more: data.has_more, }), }, ], }; } );
  • Zod input schema defining parameters for filtering and paginating transactions.
    input: z.object({ start_date: z .string() .describe("Start date in YYYY-MM-DD format"), end_date: z.string().describe("End date in YYYY-MM-DD format"), tag_id: z.number().optional().describe("Filter by tag ID"), recurring_id: z .number() .optional() .describe("Filter by recurring expense ID"), plaid_account_id: z .number() .optional() .describe("Filter by Plaid account ID"), category_id: z .number() .optional() .describe("Filter by category ID"), asset_id: z.number().optional().describe("Filter by asset ID"), is_group: z .boolean() .optional() .describe("Filter by transaction groups"), status: z .string() .optional() .describe("Filter by status: cleared, uncleared, pending"), offset: z .number() .optional() .describe("Number of transactions to skip"), limit: z .number() .optional() .describe( "Maximum number of transactions to return (max 500)" ), debit_as_negative: z .boolean() .optional() .describe("Pass true to return debit amounts as negative"), }),
  • Registration of the get_transactions tool using server.tool, including name, description, schema, and handler.
    server.tool( "get_transactions", "Retrieve transactions within a date range with optional filters", { input: z.object({ start_date: z .string() .describe("Start date in YYYY-MM-DD format"), end_date: z.string().describe("End date in YYYY-MM-DD format"), tag_id: z.number().optional().describe("Filter by tag ID"), recurring_id: z .number() .optional() .describe("Filter by recurring expense ID"), plaid_account_id: z .number() .optional() .describe("Filter by Plaid account ID"), category_id: z .number() .optional() .describe("Filter by category ID"), asset_id: z.number().optional().describe("Filter by asset ID"), is_group: z .boolean() .optional() .describe("Filter by transaction groups"), status: z .string() .optional() .describe("Filter by status: cleared, uncleared, pending"), offset: z .number() .optional() .describe("Number of transactions to skip"), limit: z .number() .optional() .describe( "Maximum number of transactions to return (max 500)" ), debit_as_negative: z .boolean() .optional() .describe("Pass true to return debit amounts as negative"), }), }, async ({ input }) => { const { baseUrl, lunchmoneyApiToken } = getConfig(); const params = new URLSearchParams({ start_date: input.start_date, end_date: input.end_date, }); if (input.tag_id !== undefined) params.append("tag_id", input.tag_id.toString()); if (input.recurring_id !== undefined) params.append("recurring_id", input.recurring_id.toString()); if (input.plaid_account_id !== undefined) params.append( "plaid_account_id", input.plaid_account_id.toString() ); if (input.category_id !== undefined) params.append("category_id", input.category_id.toString()); if (input.asset_id !== undefined) params.append("asset_id", input.asset_id.toString()); if (input.is_group !== undefined) params.append("is_group", input.is_group.toString()); if (input.status !== undefined) params.append("status", input.status); if (input.offset !== undefined) params.append("offset", input.offset.toString()); if (input.limit !== undefined) params.append("limit", input.limit.toString()); if (input.debit_as_negative !== undefined) params.append( "debit_as_negative", input.debit_as_negative.toString() ); const response = await fetch(`${baseUrl}/transactions?${params}`, { headers: { Authorization: `Bearer ${lunchmoneyApiToken}`, }, }); if (!response.ok) { return { content: [ { type: "text", text: `Failed to get transactions: ${response.statusText}`, }, ], }; } const data = await response.json(); const transactions: Transaction[] = data.transactions; return { content: [ { type: "text", text: JSON.stringify({ transactions, has_more: data.has_more, }), }, ], }; } );
  • src/index.ts:26-26 (registration)
    Top-level call to registerTransactionTools which includes the get_transactions tool.
    registerTransactionTools(server);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/akutishevsky/lunchmoney-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server