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

97 lines
3.7 KiB
C#

using System.ComponentModel;
using System.Text.Json;
using ModelContextProtocol.Server;
using MoneyMap.Models;
using MoneyMap.Services;
namespace MoneyMap.Mcp.Tools;
[McpServerToolType]
public static class BudgetTools
{
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
[McpServerTool(Name = "get_budget_status"), Description("Get all active budgets with current period spending vs. limit.")]
public static async Task<string> GetBudgetStatus(
[Description("Date to calculate status for (defaults to today)")] string? asOfDate = null,
IBudgetService budgetService = default!)
{
DateTime? date = null;
if (!string.IsNullOrWhiteSpace(asOfDate) && DateTime.TryParse(asOfDate, out var parsed))
date = parsed;
var statuses = await budgetService.GetAllBudgetStatusesAsync(date);
var result = statuses.Select(s => new
{
s.Budget.Id,
Category = s.Budget.DisplayName,
s.Budget.Amount,
Period = s.Budget.Period.ToString(),
s.PeriodStart,
s.PeriodEnd,
s.Spent,
s.Remaining,
PercentUsed = Math.Round(s.PercentUsed, 1),
s.IsOverBudget
}).ToList();
return JsonSerializer.Serialize(result, JsonOptions);
}
[McpServerTool(Name = "create_budget"), Description("Create a new budget for a category or total spending.")]
public static async Task<string> CreateBudget(
[Description("Budget amount limit")] decimal amount,
[Description("Period: Weekly, Monthly, or Yearly")] string period,
[Description("Start date for period calculation, e.g. 2026-01-01")] string startDate,
[Description("Category name (omit for total spending budget)")] string? category = null,
IBudgetService budgetService = default!)
{
if (!Enum.TryParse<BudgetPeriod>(period, true, out var budgetPeriod))
return $"Invalid period '{period}'. Must be Weekly, Monthly, or Yearly.";
var budget = new Budget
{
Category = category,
Amount = amount,
Period = budgetPeriod,
StartDate = DateTime.Parse(startDate),
IsActive = true
};
var result = await budgetService.CreateBudgetAsync(budget);
return JsonSerializer.Serialize(new { result.Success, result.Message, BudgetId = budget.Id }, JsonOptions);
}
[McpServerTool(Name = "update_budget"), Description("Update an existing budget's amount, period, or active status.")]
public static async Task<string> UpdateBudget(
[Description("Budget ID to update")] int budgetId,
[Description("New budget amount")] decimal? amount = null,
[Description("New period: Weekly, Monthly, or Yearly")] string? period = null,
[Description("Set active/inactive")] bool? isActive = null,
IBudgetService budgetService = default!)
{
var budget = await budgetService.GetBudgetByIdAsync(budgetId);
if (budget == null)
return "Budget not found";
if (amount.HasValue)
budget.Amount = amount.Value;
if (!string.IsNullOrWhiteSpace(period))
{
if (!Enum.TryParse<BudgetPeriod>(period, true, out var budgetPeriod))
return $"Invalid period '{period}'. Must be Weekly, Monthly, or Yearly.";
budget.Period = budgetPeriod;
}
if (isActive.HasValue)
budget.IsActive = isActive.Value;
var result = await budgetService.UpdateBudgetAsync(budget);
return JsonSerializer.Serialize(new { result.Success, result.Message }, JsonOptions);
}
}