using System.ComponentModel; using System.Net.Http.Json; using System.Text.Json; using ModelContextProtocol.Server; namespace TaskTracker.MCP.Tools; [McpServerToolType] public sealed class TaskTools { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; [McpServerTool, Description("Get the currently active work task with its latest notes and recent context events")] public static async Task GetActiveTask(HttpClient client) { var response = await client.GetAsync("/api/tasks/active"); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("List work tasks, optionally filtered by status (Pending, Active, Paused, Completed, Abandoned)")] public static async Task ListTasks( HttpClient client, [Description("Filter by status: Pending, Active, Paused, Completed, Abandoned")] string? status = null) { var url = "/api/tasks"; if (!string.IsNullOrEmpty(status)) url += $"?status={status}"; var response = await client.GetAsync(url); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Create a new work task")] public static async Task CreateTask( HttpClient client, [Description("Title of the task")] string title, [Description("Optional description")] string? description = null, [Description("Optional category (e.g. Engineering, Email, LaserCutting)")] string? category = null) { var payload = new { title, description, category }; var response = await client.PostAsJsonAsync("/api/tasks", payload, JsonOptions); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Start/activate a task by ID. Automatically pauses any currently active task.")] public static async Task StartTask( HttpClient client, [Description("The task ID to start")] int taskId) { var response = await client.PutAsync($"/api/tasks/{taskId}/start", null); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Pause a task with an optional note about why it was paused")] public static async Task PauseTask( HttpClient client, [Description("The task ID to pause")] int taskId, [Description("Optional note about why the task is being paused")] string? note = null) { var payload = new { note }; var response = await client.PutAsJsonAsync($"/api/tasks/{taskId}/pause", payload, JsonOptions); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Resume a paused task with an optional note about context for resuming")] public static async Task ResumeTask( HttpClient client, [Description("The task ID to resume")] int taskId, [Description("Optional note about context for resuming")] string? note = null) { var payload = new { note }; var response = await client.PutAsJsonAsync($"/api/tasks/{taskId}/resume", payload, JsonOptions); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Mark a task as complete")] public static async Task CompleteTask( HttpClient client, [Description("The task ID to complete")] int taskId) { var response = await client.PutAsync($"/api/tasks/{taskId}/complete", null); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Add a note to a task")] public static async Task AddNote( HttpClient client, [Description("The task ID")] int taskId, [Description("The note content")] string content, [Description("Note type: General, PauseNote, or ResumeNote")] string type = "General") { var payload = new { content, type }; var response = await client.PostAsJsonAsync($"/api/tasks/{taskId}/notes", payload, JsonOptions); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Get a summary of recent window/browser activity grouped by application, useful for understanding what the user has been working on")] public static async Task GetContextSummary(HttpClient client) { var response = await client.GetAsync("/api/context/summary"); return await response.Content.ReadAsStringAsync(); } [McpServerTool, Description("Get raw context events (window switches, browser navigations) from the last N minutes")] public static async Task GetRecentContext( HttpClient client, [Description("Number of minutes to look back (default 30)")] int minutes = 30) { var response = await client.GetAsync($"/api/context/recent?minutes={minutes}"); return await response.Content.ReadAsStringAsync(); } }