using System.ComponentModel; using ModelContextProtocol.Protocol; using ModelContextProtocol.Server; namespace Novelly.Mcp.Tools; [McpServerToolType] public static class ManuscriptTools { [McpServerTool(Name = "list_chapters")] [Description("List a novel's chapters in manuscript order, with beat and word counts.")] public static Task ListChapters( NovelApiClient api, [Description("The novel's id.")] Guid novelId, CancellationToken ct) => api.GetAsync($"/api/novels/{novelId}/chapters", ct); [McpServerTool(Name = "get_chapter")] [Description("Read one chapter in full: its outline (beats) and its drafted prose.")] public static Task GetChapter( NovelApiClient api, [Description("The chapter's id.")] Guid chapterId, CancellationToken ct) => api.GetAsync($"/api/chapters/{chapterId}", ct); [McpServerTool(Name = "create_chapter")] [Description("Add a chapter to a novel. It goes at the end of the manuscript unless you supply a number.")] public static Task CreateChapter( NovelApiClient api, [Description("The novel's id.")] Guid novelId, [Description("Chapter title.")] string title, CancellationToken ct, [Description("Position in the manuscript, 1-based.")] int? number = null, [Description("The chapter's outline summary paragraph.")] string? summary = null, [Description("Where and when the chapter takes place. Unknown locations are created.")] string[]? locations = null, [Description("Planned, Outlined, Drafted, Revised or Final.")] string? status = null, [Description("Target length in words.")] int? targetWordCount = null, [Description("The chapter's drafted text, in markdown, if you are writing it now.")] string? prose = null, [Description("Tags for cross-referencing. Unknown tags are created.")] string[]? tags = null) => api.PostAsync($"/api/novels/{novelId}/chapters", new { title, number, summary, locations, status = status ?? "Planned", targetWordCount, prose, tags }, ct); [McpServerTool(Name = "update_chapter")] [Description("Revise a chapter's title, number, summary, locations, notes, status " + "or drafted prose. Use 'prose' to write or replace the chapter's draft text in " + "markdown; the word count is recomputed automatically.")] public static Task UpdateChapter( NovelApiClient api, [Description("The chapter's id.")] Guid chapterId, CancellationToken ct, [Description("New title.")] string? title = null, [Description("Position in the manuscript.")] int? number = null, [Description("The chapter's outline summary paragraph.")] string? summary = null, [Description("Where and when the chapter takes place. Replaces the existing locations. Unknown locations are created.")] string[]? locations = null, [Description("Anything else worth recording.")] string? notes = null, [Description("Planned, Outlined, Drafted, Revised or Final.")] string? status = null, [Description("Target length in words.")] int? targetWordCount = null, [Description("The chapter's drafted text, in markdown.")] string? prose = null, [Description("Tags for cross-referencing. Replaces the existing tags.")] string[]? tags = null) => api.PatchAsync($"/api/chapters/{chapterId}", new { title, number, summary, locations, notes, status, targetWordCount, prose, tags }, ct); }