using System.ComponentModel; using ModelContextProtocol.Protocol; using ModelContextProtocol.Server; namespace Novelly.Mcp.Tools; [McpServerToolType] public static class ProjectTools { [McpServerTool(Name = "list_projects")] [Description("List every novel project, with counts of characters, chapters and drafted words. " + "Start here to find the project id everything else needs.")] public static Task ListProjects(NovelApiClient api, CancellationToken ct) => api.GetAsync("/api/projects", ct); [McpServerTool(Name = "get_project_brief")] [Description("Read a project's title, author, genre, logline, synopsis, notes and word-count target.")] public static Task GetProject( NovelApiClient api, [Description("The project's id.")] Guid projectId, CancellationToken ct) => api.GetAsync($"/api/projects/{projectId}", ct); [McpServerTool(Name = "create_project")] [Description("Create a new novel project.")] public static Task CreateProject( NovelApiClient api, [Description("Working title.")] string title, CancellationToken ct, [Description("Author name.")] string? author = null, [Description("Genre or category.")] string? genre = null, [Description("One-sentence pitch.")] string? logline = null, [Description("Paragraph-length summary of the whole book.")] string? synopsis = null, [Description("Free-form notes on theme, tone, comparable titles.")] string? notes = null, [Description("Target manuscript length in words.")] int? targetWordCount = null) => api.PostAsync("/api/projects", new { title, author, genre, logline, synopsis, notes, targetWordCount }, ct); [McpServerTool(Name = "update_project_brief")] [Description("Revise a project's top-level fields. Only the fields you supply change; " + "pass an empty string to clear one.")] public static Task UpdateProject( NovelApiClient api, [Description("The project's id.")] Guid projectId, CancellationToken ct, [Description("New title.")] string? title = null, [Description("Author name.")] string? author = null, [Description("Genre or category.")] string? genre = null, [Description("One-sentence pitch.")] string? logline = null, [Description("Paragraph-length summary of the whole book.")] string? synopsis = null, [Description("Free-form notes on theme, tone, comparable titles.")] string? notes = null, [Description("Target manuscript length in words.")] int? targetWordCount = null) => api.PatchAsync($"/api/projects/{projectId}", new { title, author, genre, logline, synopsis, notes, targetWordCount }, ct); }