274569bd79
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
78 lines
4.5 KiB
C#
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);
|
|
}
|
|
}
|