UNPKG

@baruchiro/actual-mcp

Version:

Actual Budget MCP server exposing API functionality

62 lines 3.25 kB
import { GetTransactionsInputParser } from './input-parser.js'; import { GetTransactionsDataFetcher } from './data-fetcher.js'; import { GetTransactionsMapper } from './transaction-mapper.js'; import { GetTransactionsReportGenerator } from './report-generator.js'; import { success, errorFromCatch } from '../../utils/response.js'; import { getDateRange } from '../../utils.js'; import { GetTransactionsArgsSchema } from '../../types.js'; import { zodToJsonSchema } from 'zod-to-json-schema'; export const schema = { name: 'get-transactions', description: 'Get transactions with optional filtering. Supports filtering by date range, amount, category, payee, and uncategorized transactions. If accountId is not provided, returns transactions for all on-budget accounts. Use get-accounts tool to discover available account IDs.', inputSchema: zodToJsonSchema(GetTransactionsArgsSchema), }; export async function handler(args) { try { const input = new GetTransactionsInputParser().parse(args); const { accountId, startDate, endDate, minAmount, maxAmount, categoryName, payeeName, uncategorizedOnly, limit } = input; const { startDate: start, endDate: end } = getDateRange(startDate, endDate); // Fetch transactions const transactions = await new GetTransactionsDataFetcher().fetch(accountId, start, end); let filtered = [...transactions]; if (minAmount !== undefined) { filtered = filtered.filter((t) => t.amount >= minAmount * 100); } if (maxAmount !== undefined) { filtered = filtered.filter((t) => t.amount <= maxAmount * 100); } if (categoryName) { const lowerCategory = categoryName.toLowerCase(); filtered = filtered.filter((t) => (t.category_name || '').toLowerCase().includes(lowerCategory)); } if (payeeName) { const lowerPayee = payeeName.toLowerCase(); filtered = filtered.filter((t) => (t.payee_name || '').toLowerCase().includes(lowerPayee)); } if (uncategorizedOnly) { filtered = filtered.filter((t) => !t.category && !t.category_name && !t.transfer_id); } if (limit && filtered.length > limit) { filtered = filtered.slice(0, limit); } // Map transactions for output const mapped = new GetTransactionsMapper().map(filtered); // Build filter description const filterDescription = [ startDate || endDate ? `Date range: ${startDate} to ${endDate}` : null, minAmount !== undefined ? `Min amount: $${minAmount.toFixed(2)}` : null, maxAmount !== undefined ? `Max amount: $${maxAmount.toFixed(2)}` : null, categoryName ? `Category: ${categoryName}` : null, payeeName ? `Payee: ${payeeName}` : null, uncategorizedOnly ? 'Uncategorized only' : null, ] .filter(Boolean) .join(', '); const markdown = new GetTransactionsReportGenerator().generate(mapped, filterDescription, filtered.length, transactions.length); return success(markdown); } catch (err) { return errorFromCatch(err); } } //# sourceMappingURL=index.js.map