Files
MoneyMap/MoneyMap.Mcp/Tools/TransactionTools.cs
T

78 lines
4.5 KiB
C#

using System.ComponentModel;
using ModelContextProtocol.Server;
namespace MoneyMap.Mcp.Tools;
[McpServerToolType]
public static class TransactionTools
{
[McpServerTool(Name = "search_transactions"), Description("Search and filter transactions. Returns matching transactions with details.")]
public static async Task<string> SearchTransactions(
[Description("Full-text search across name, memo, and category")] string? query = null,
[Description("Start date (inclusive), e.g. 2026-01-01")] string? startDate = null,
[Description("End date (inclusive), e.g. 2026-01-31")] string? endDate = null,
[Description("Filter by category name (exact match)")] string? category = null,
[Description("Filter by merchant name (contains)")] string? merchantName = null,
[Description("Minimum amount (absolute value)")] decimal? minAmount = null,
[Description("Maximum amount (absolute value)")] decimal? maxAmount = null,
[Description("Filter by account ID")] int? accountId = null,
[Description("Filter by card ID")] int? cardId = null,
[Description("Filter by type: 'debit' or 'credit'")] string? type = null,
[Description("Only show uncategorized transactions")] bool? uncategorizedOnly = null,
[Description("Max results to return (default 50)")] int? limit = null,
MoneyMapApiClient api = default!)
{
return await api.SearchTransactionsAsync(query, startDate, endDate, category, merchantName, minAmount, maxAmount, accountId, cardId, type, uncategorizedOnly, limit);
}
[McpServerTool(Name = "get_transaction"), Description("Get a single transaction with all details including receipts.")]
public static async Task<string> GetTransaction(
[Description("Transaction ID")] long transactionId,
MoneyMapApiClient api = default!)
{
return await api.GetTransactionAsync(transactionId);
}
[McpServerTool(Name = "get_spending_summary"), Description("Get spending totals grouped by category for a date range. Excludes transfers.")]
public static async Task<string> GetSpendingSummary(
[Description("Start date (inclusive), e.g. 2026-01-01")] string startDate,
[Description("End date (inclusive), e.g. 2026-01-31")] string endDate,
[Description("Filter to specific account ID")] int? accountId = null,
MoneyMapApiClient api = default!)
{
return await api.GetSpendingSummaryAsync(startDate, endDate, accountId);
}
[McpServerTool(Name = "get_income_summary"), Description("Get income (credits) grouped by source/name for a date range.")]
public static async Task<string> GetIncomeSummary(
[Description("Start date (inclusive), e.g. 2026-01-01")] string startDate,
[Description("End date (inclusive), e.g. 2026-01-31")] string endDate,
[Description("Filter to specific account ID")] int? accountId = null,
MoneyMapApiClient api = default!)
{
return await api.GetIncomeSummaryAsync(startDate, endDate, accountId);
}
[McpServerTool(Name = "update_transaction_category"), Description("Update the category (and optionally merchant) on one or more transactions.")]
public static async Task<string> UpdateTransactionCategory(
[Description("Array of transaction IDs to update")] long[] transactionIds,
[Description("New category to assign")] string category,
[Description("Merchant name to assign (creates if new)")] string? merchantName = null,
MoneyMapApiClient api = default!)
{
return await api.UpdateTransactionCategoryAsync(transactionIds, category, merchantName);
}
[McpServerTool(Name = "bulk_recategorize"), Description("Recategorize all transactions matching a name pattern. Use dryRun=true (default) to preview changes first.")]
public static async Task<string> BulkRecategorize(
[Description("Pattern to match in transaction name (case-insensitive contains)")] string namePattern,
[Description("New category to assign")] string toCategory,
[Description("Only recategorize transactions currently in this category")] string? fromCategory = null,
[Description("Merchant name to assign (creates if new)")] string? merchantName = null,
[Description("If true (default), only shows what would change without applying")] bool dryRun = true,
MoneyMapApiClient api = default!)
{
return await api.BulkRecategorizeAsync(namePattern, toCategory, fromCategory, merchantName, dryRun);
}
}