Files
FsMcp/FsMcp/Tools/StorePickupsTools.cs

105 lines
3.3 KiB
C#

using System.ComponentModel;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using FsMcp;
using ModelContextProtocol.Server;
namespace FsMcp.Tools;
internal sealed class StorePickupsTools
{
private readonly FoodsharingApiClient _apiClient;
public StorePickupsTools(FoodsharingApiClient apiClient)
{
_apiClient = apiClient;
}
[McpServerTool]
[Description("List upcoming pickups for a store from GET /api/stores/{storeId}/pickups.")]
public async Task<IReadOnlyList<StorePickup>> GetStorePickupsAsync(
[Description("Store ID as positive integer.")]
int storeId)
{
if (storeId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(storeId), "storeId must be a positive integer.");
}
await _apiClient.EnsureLoginAsync();
var pickups = await _apiClient.HttpClient.GetFromJsonAsync<IReadOnlyList<StorePickup>>(Endpoints.StorePickups(storeId));
return pickups ?? [];
}
}
public sealed record StorePickup
{
[Description("Date and time of the pickup.")]
[JsonPropertyName("date")]
public DateTime Date { get; init; }
[Description("Total number of available slots for this pickup.")]
[JsonPropertyName("totalSlots")]
public int TotalSlots { get; init; }
[Description("List of slots already occupied by users.")]
[JsonPropertyName("occupiedSlots")]
[JsonConverter(typeof(ObjectOrArrayConverter<OccupiedSlot>))]
public IReadOnlyList<OccupiedSlot> OccupiedSlots { get; init; } = [];
[Description("Whether slots are still available for this pickup.")]
[JsonPropertyName("isAvailable")]
[JsonConverter(typeof(NumberOrBoolConverter))]
public bool IsAvailable { get; init; }
[Description("Description or instructions for the pickup.")]
[JsonPropertyName("description")]
public string Description { get; init; } = string.Empty;
}
public sealed record OccupiedSlot
{
[Description("Whether the user's participation is confirmed.")]
[JsonPropertyName("isConfirmed")]
[JsonConverter(typeof(NumberOrBoolConverter))]
public bool IsConfirmed { get; init; }
[Description("Profile of the user who occupied the slot.")]
[JsonPropertyName("profile")]
public PickupUserProfile Profile { get; init; } = new();
}
public sealed record PickupUserProfile
{
[Description("User identifier.")]
[JsonPropertyName("id")]
public int Id { get; init; }
[Description("User display name.")]
[JsonPropertyName("name")]
public string Name { get; init; } = string.Empty;
[Description("URL to the user's avatar image.")]
[JsonPropertyName("avatar")]
public string? Avatar { get; init; }
[Description("Whether the user is currently in sleep mode.")]
[JsonPropertyName("isSleeping")]
[JsonConverter(typeof(NumberOrBoolConverter))]
public bool IsSleeping { get; init; }
[Description("Mobile phone number.")]
[JsonPropertyName("mobile")]
public string? Mobile { get; init; }
[Description("Landline phone number.")]
[JsonPropertyName("landline")]
public string? Landline { get; init; }
[Description("Whether the user is a store manager.")]
[JsonPropertyName("isManager")]
[JsonConverter(typeof(NumberOrBoolConverter))]
public bool IsManager { get; init; }
}