Adds SoftDelete/Trash across characters, chapters, locations, beats with a purge schedule and Trash page. Reworks the web client for keyboard-driven navigation (focus helpers, help overlay, keyboard.md doc). Moves the ChapterPage tag editor to the bottom of the page to match CharacterDetailPage.
55 lines
2.5 KiB
C#
55 lines
2.5 KiB
C#
using System.ComponentModel;
|
|
using ModelContextProtocol.Protocol;
|
|
using ModelContextProtocol.Server;
|
|
|
|
namespace Novelly.Mcp.Tools;
|
|
|
|
[McpServerToolType]
|
|
public static class LocationTools
|
|
{
|
|
[McpServerTool(Name = "list_locations")]
|
|
[Description("List a novel's locations with how many chapters are set there. "
|
|
+ "Read this before inventing a new location so you reuse the writer's vocabulary.")]
|
|
public static Task<CallToolResult> ListLocations(
|
|
NovelApiClient api,
|
|
[Description("The novel's id.")] Guid novelId,
|
|
CancellationToken ct) =>
|
|
api.GetAsync($"/api/novels/{novelId}/locations", ct);
|
|
|
|
[McpServerTool(Name = "get_location_references")]
|
|
[Description("Cross-reference a location: every chapter set there.")]
|
|
public static Task<CallToolResult> GetLocationReferences(
|
|
NovelApiClient api,
|
|
[Description("The location's id.")] Guid locationId,
|
|
CancellationToken ct) =>
|
|
api.GetAsync($"/api/locations/{locationId}/references", ct);
|
|
|
|
[McpServerTool(Name = "create_location")]
|
|
[Description("Create a location explicitly. Applying an unknown location by name to a chapter "
|
|
+ "also creates it, so this is only needed to set one up ahead of time.")]
|
|
public static Task<CallToolResult> CreateLocation(
|
|
NovelApiClient api,
|
|
[Description("The novel's id.")] Guid novelId,
|
|
[Description("The location's name. Unique within the novel, matched case-insensitively.")] string name,
|
|
CancellationToken ct) =>
|
|
api.PostAsync($"/api/novels/{novelId}/locations", new { name }, ct);
|
|
|
|
[McpServerTool(Name = "update_location")]
|
|
[Description("Rename a location. Renaming updates it everywhere it is applied.")]
|
|
public static Task<CallToolResult> UpdateLocation(
|
|
NovelApiClient api,
|
|
[Description("The location's id.")] Guid locationId,
|
|
[Description("New name.")] string name,
|
|
CancellationToken ct) =>
|
|
api.PatchAsync($"/api/locations/{locationId}", new { name }, ct);
|
|
|
|
[McpServerTool(Name = "delete_location")]
|
|
[Description("Move a location to the trash. Whatever carried it is left alone — only the label goes. "
|
|
+ "It can be restored from the Trash page within the retention window.")]
|
|
public static Task<CallToolResult> DeleteLocation(
|
|
NovelApiClient api,
|
|
[Description("The location's id.")] Guid locationId,
|
|
CancellationToken ct) =>
|
|
api.DeleteAsync($"/api/locations/{locationId}", ct);
|
|
}
|