MCP tool reference
The Anthra MCP server is at full parity with the in-app AI writing agent — 266+ tools spanning planning, drafting, prose analysis, the specialist critique panel, worldbuilding & continuity, character craft, structural editing, collaboration, illustration, narration, and publishing.
The authoritative, always-current list lives at the source. Because new tools ship continuously, the canonical catalog — every tool name, description, and JSON Schema — is whatever your client receives on the MCP tools/list request, or from GET /api/v1/tools over the REST tool gateway. The groups below are a representative map; they are generated from the same definitions the server serves, but treat the live list as canonical.
Each tool is gated by the API scope it requires (books:read, books:write, generation:run, publish:write, account:read, analytics:read). Schemas are JSON Schema, exactly as the MCP client sees them. Expand any tool for its input schema and the scope it needs.
Library & books
List, read, create, import, update, delete, and restore books and their metadata.
list_booksbooks:readList every book in this account (newest first). Returns id, title, status, visibility, slug.
Input schema
{ "type": "object", "properties": {} }get_bookbooks:readFetch a single book with its full chapter list (titles, summaries, content, word counts, audio URLs).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }create_bookbooks:writeCreate a draft book from a one-line premise. Returns the book id, which subsequent generation tools accept. After creating, call `generate_outline`.
Input schema
{ "type": "object", "properties": { "premise": { "type": "string", "minLength": 10, "description": "One-paragraph book idea (10–4000 chars)." }, "title": { "type": "string", "maxLength": 200 }, "genre": { "type": "string", "maxLength": 120 }, "modelTier": { "type": "string", "enum": [ "haiku", "sonnet", "opus" ], "description": "Writer model tier: haiku=fast draft, sonnet=default, opus=editorial." } }, "required": [ "premise" ] }import_bookbooks:writeCreate a new book from a manuscript the author already wrote — a true upload, no AI prose generation. Pass EITHER `chapters` (an explicit ordered list of {title, content}, committed verbatim) OR a single `text` blob (Markdown or plain text) that is auto-split into chapters. Max 4 MB per call. Returns the new bookId; the imported book lands in status `ready`, so it can be published or edited immediately. The import is free; the optional AI cleanup pass on `text` (refine, default on) charges 1 assist credit per ~50 detected chapters when it runs (skipped with a warning if credits are short; refunded if it falls back).
Input schema
{ "type": "object", "properties": { "title": { "type": "string", "maxLength": 200, "description": "Book title. Falls back to a detected/placeholder title." }, "subtitle": { "type": "string", "maxLength": 300 }, "author": { "type": "string", "maxLength": 200 }, "chapters": { "type": "array", "minItems": 1, "maxItems": 2000, "items": { "type": "object", "properties": { "title": { "type": "string", "minLength": 1, "maxLength": 200 }, "content": { "type": "string", "minLength": 1 } }, "required": [ "title", "content" ] }, "description": "Explicit chapter list, committed verbatim. Takes precedence over `text`." }, "text": { "type": "string", "description": "Full manuscript as Markdown or plain text. Chapters are detected from headings / blank-line breaks. Ignored if `chapters` is provided." }, "format": { "type": "string", "enum": [ "markdown", "txt" ], "description": "How to interpret `text` (default markdown). Ignored if `chapters` is provided." }, "refine": { "type": "boolean", "description": "When importing from `text`, run a cheap AI pass that merges over-split chapters and cleans titles (default true). Has no effect on `chapters`." }, "sourceLabel": { "type": "string", "maxLength": 200, "description": "Provenance label stored on the book (e.g. a filename or \"exported from Notion\")." } } }update_bookbooks:writePatch a book's metadata (title, subtitle, description, author, cover color, genre, tone). Does not touch chapters.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "title": { "type": "string" }, "subtitle": { "type": "string" }, "author": { "type": "string" }, "description": { "type": "string" }, "coverColor": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" }, "genre": { "type": "string" }, "audience": { "type": "string" }, "toneStyle": { "type": "string" } }, "required": [ "bookId" ] }delete_bookbooks:writeSoft-delete a book. Recoverable within 30 days, after which the cron worker hard-deletes it.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }undo_delete_bookbooks:writeRestore a recently soft-deleted book. Works within 30 days of deletion (after that the cleanup cron hard-deletes the row). Clears the archived flag too so the book returns to the active library.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }
Versions & history
Save, preview and restore whole-book versions, and bring back recently deleted chapters. Every restore auto-saves the current state first.
list_book_versionsbooks:readList a book's saved versions (whole-book snapshots), newest first: label, kind (manual = saved on purpose; auto = saved by Anthra before outline regeneration, import replace, translate, generation over written prose, or a restore), reason, chapter/word counts, createdAt. Free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }get_book_versionbooks:readPreview one saved version: the book fields it holds plus each chapter's id, title, word count and a 400-character excerpt. Free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "versionId": { "type": "string", "description": "Version UUID from list_book_versions." } }, "required": [ "bookId", "versionId" ] }save_book_versionbooks:writeSave the book's current state — every chapter's prose and outline fields plus title/subtitle/premise — as a manual version that can be restored later. Free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "label": { "type": "string", "description": "Optional name (max 120 chars)." } }, "required": [ "bookId" ] }restore_book_versionbooks:writeRestore a saved version over the current book: chapters are rewritten, recreated or removed and title/subtitle/premise reset to match the version. The current state is auto-saved as a version first (returned as safetyVersionId), so the restore can be undone. Refused while a generation run is active. Requires confirm: true. Free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "versionId": { "type": "string", "description": "Version UUID from list_book_versions." }, "confirm": { "type": "boolean", "description": "Must be true — this replaces the current book state." } }, "required": [ "bookId", "versionId", "confirm" ] }list_deleted_chaptersbooks:readList a book's recently deleted chapters whose last prose was kept: revisionId, title, old position (order), word count, deletedAt, reason. Restore with restore_deleted_chapter. Free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }restore_deleted_chapterbooks:writeBring a deleted chapter back at its old position from its last saved prose (later chapters shift down one). Pass revisionId from list_deleted_chapters. Requires confirm: true. Free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "revisionId": { "type": "string", "description": "revisionId from list_deleted_chapters." }, "confirm": { "type": "boolean", "description": "Must be true." } }, "required": [ "bookId", "revisionId", "confirm" ] }
Planning surface
Theme statement, reader promise, comp authors, beat sheets, POV/tense locks, premise interview & pitches, genre detect, era research, outline grader, outline variants, mood references, and outline snapshots.
generate_outlinegeneration:runRun the outliner: replaces any existing chapters with a fresh outline, sets title/subtitle/description/coverColor on the book, and advances status to `writing`. Synchronous — may take 10–60s. PAID — charges outline credits (+ research credits when the research pass runs); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "research": { "type": "boolean", "description": "Force-enable the Perplexity research pass before outlining. Defaults to the account-wide flag." } }, "required": [ "bookId" ] }get_planbooks:readRead the book's planning surface — theme statement, reader promise, comp authors, selected beat sheet, POV/tense locks, auto-detected genre + audience confidences, and era-research citations.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }set_planbooks:writeWrite the planning surface fields. Any omitted field is left alone; pass null to clear. Fields: themeStatement, readerPromise, compAuthors, beatSheetTemplate (id like 'save-the-cat'), povLock, tenseLock ('past'|'present'), povDepth (0-100).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "themeStatement": { "type": [ "string", "null" ] }, "readerPromise": { "type": [ "string", "null" ] }, "compAuthors": { "type": [ "string", "null" ] }, "beatSheetTemplate": { "type": [ "string", "null" ] }, "povLock": { "type": [ "string", "null" ] }, "tenseLock": { "type": [ "string", "null" ], "enum": [ "past", "present", null ] }, "povDepth": { "type": [ "integer", "null" ], "minimum": 0, "maximum": 100 } }, "required": [ "bookId" ] }list_beat_sheetsbooks:readList every beat-sheet template (Save the Cat, Three-Act, Hero's Journey, Freytag, Kishotenketsu, Tell/Promise/Mean) with each beat's label, intent, and position.
Input schema
{ "type": "object", "properties": {} }premise_interviewgeneration:runPremise-sharpening interview. action='read' returns saved state; 'generate' produces 3-5 questions; 'save' merges answers (q1, q2, …); 'apply' rewrites book.premise from answers. PAID — 'generate' and 'apply' each charge 1 assist credit (refunded on failure); 'read'/'save' are free.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "action": { "type": "string", "enum": [ "read", "generate", "save", "apply" ] }, "answers": { "type": "object" } }, "required": [ "bookId", "action" ] }generate_premise_pitchesgeneration:runThree competing premise pitches (A/B/C angles for the same idea). Use select_premise_pitch to lock one. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }list_premise_pitchesbooks:readList the most recent round of premise pitches.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }select_premise_pitchbooks:writeLock one premise pitch (writes book.premise).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "angle": { "type": "string", "enum": [ "A", "B", "C" ] } }, "required": [ "bookId", "angle" ] }detect_genregeneration:runAuto-detect genre + audience from the current premise. apply:true writes the result to the book. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "apply": { "type": "boolean" } }, "required": [ "bookId" ] }research_erageneration:runEra / period research with citation links. Writes a Markdown brief into the era_research writer's-bible document and saves the citations to book.researchCitations. PAID — charges 1 research credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "eraHint": { "type": [ "string", "null" ] } }, "required": [ "bookId" ] }grade_outlinegeneration:runScore the current outline 0-100 across arc / pacing / stakes / characters / ending, with a paragraph-level critique and 2-8 fix suggestions. force:true regrades even if cached. PAID — a fresh grade charges 1 critique credit (cached grades are free); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "force": { "type": "boolean" } }, "required": [ "bookId" ] }list_outline_variantsbooks:readList the most recent round of outline variants (#14).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }generate_outline_variantsgeneration:runThree competing outline variants (each with a one-line angle + a full chapter list). Costs three outline-LLM calls. PAID — charges 3 outline credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }apply_outline_variantbooks:writeApply one outline variant to the chapter table (snapshots first, skips locked chapters).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "variantId": { "type": "string" } }, "required": [ "bookId", "variantId" ] }list_outline_snapshotsbooks:readList every captured outline mutation (#22) — pair with restore_outline_snapshot.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }restore_outline_snapshotbooks:writeRevert the outline to a saved snapshot in place.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "snapshotId": { "type": "string" } }, "required": [ "bookId", "snapshotId" ] }list_mood_referencesbooks:readList tone / mood reference photos (#12) for this book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }generate_chapter_imagegeneration:runGenerate an illustration for one chapter via the AI Gateway image pipeline, store it in Vercel Blob, and set it as the chapter's lead image. PAID — charges one illustration credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "styleHint": { "type": "string", "description": "Art-direction hint (e.g. \"muted watercolor\")." }, "prompt": { "type": "string", "description": "Override the distilled prompt." } }, "required": [ "bookId", "chapterId" ] }generate_cover_artgeneration:runGenerate one or more cover-art variants via the AI Gateway image pipeline, store in Vercel Blob, and set the first as the book's active cover. PAID — charges per variant (1-3); refunds the unspent portion on partial failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "styleHint": { "type": "string", "description": "Art-direction (e.g. \"moody oil painting\")." }, "prompt": { "type": "string", "description": "Hand-crafted prompt override." }, "variants": { "type": "integer", "minimum": 1, "maximum": 3 } }, "required": [ "bookId" ] }generate_back_covergeneration:runGenerate a back-cover panel via the AI Gateway image pipeline. Uses the marketing blurb when present, otherwise the premise. PAID — one illustration credit.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "prompt": { "type": "string" }, "styleHint": { "type": "string" } }, "required": [ "bookId" ] }generate_spinegeneration:runGenerate a spine panel via the AI Gateway image pipeline. Narrow aspect ratio sized for paperback spines. PAID — one illustration credit.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "prompt": { "type": "string" }, "styleHint": { "type": "string" } }, "required": [ "bookId" ] }generate_cover_wrapgeneration:runGenerate one continuous wraparound illustration (back + spine + front) laid out for the book size and page count, and select it as the print cover art. Text-free — title, author and blurb are set as type on export. PAID — one illustration credit.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "prompt": { "type": "string", "maxLength": 800 } }, "required": [ "bookId" ] }cancel_generationbooks:writeCancel the active book-generation workflow run for one book (the long-running outline-and-write pipeline). Idempotent — succeeds with ok:true even when no run is active. Reverts book status to `draft`.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }generate_bookgeneration:runStart the durable end-to-end generation pipeline for a book (research → outline → write every chapter → continuity pass → finalize) and return immediately with a runId. Unlike calling write_chapter in a loop, this survives serverless timeouts and crashes (it runs on the Workflow runtime), so it is the right way for an external agent to generate a whole book. Poll progress with get_book (watch `status`: writing → ready) or subscribe to the `job.succeeded` / `job.failed` webhook. Credits for the unwritten work (outline + chapters, or just the empty chapters) are charged up front; if the run fails or is cancelled, the share for chapters it did not write is refunded. Refuses if a run is already active for this book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }update_mood_reference_captionbooks:writeEdit the caption on a mood reference image (#12). The caption is what actually feeds the writer prompt (register, palette, weather, light); the image is for the author.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "imageId": { "type": "string" }, "caption": { "type": "string" } }, "required": [ "bookId", "imageId", "caption" ] }remove_mood_referencebooks:writeDelete a mood reference image (#12) from this book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "imageId": { "type": "string" } }, "required": [ "bookId", "imageId" ] }plan_deadlinegeneration:runPlan remaining writing against a target date. Returns weekly + daily word targets, a feasibility verdict, suggested cuts, and ramps. Uses outline target words + currently written words. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "targetDate": { "type": "string", "description": "ISO date string, e.g. \"2026-09-01\"." }, "targetTotalWords": { "type": "number", "description": "Target total word count. If omitted, sums the outline's per-chapter targetWords (or 3000/chapter when missing)." }, "recentWordsPerWeek": { "type": "number", "description": "If known, the author's recent pace in words/week." }, "constraints": { "type": "string" } }, "required": [ "bookId", "targetDate" ] }genre_expert_lookupgeneration:runGenre expert lookup. Ask a question about genre conventions, comp-title moves, or reader expectations — the Genre Expert returns canonical prescriptions an author can apply tomorrow. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "question": { "type": "string", "description": "The question, e.g. 'what's the cozy-mystery midpoint move?'." }, "genre": { "type": "string", "description": "Override genre. Defaults to the book's genre if bookId is provided." }, "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "question" ] }generate_invented_calendargeneration:runGenerate a complete invented calendar for the book — months, day length, day-of-week names, festivals (#45). Does NOT save the result. Pass the returned shape to set_invented_calendar to persist. Costs LLM tokens. PAID: charges 1 credit (assist); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "styleHint": { "type": "string" } }, "required": [ "bookId" ] }regenerate_relationship_graphgeneration:runRe-derive the character relationship graph (#95) from the full prose. Replaces book_character_conflict with model-extracted directed edges (kind + one-line description). Costs LLM tokens proportional to manuscript size. PAID: charges the assist rate × manuscript size (1 credit per ~25k words scanned, min 1 — ~4–5 for a typical novel); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "replace": { "type": "boolean", "description": "When true, wipes existing conflicts before insert. Defaults to false (additive, dedup'd by from+to+kind)." } }, "required": [ "bookId" ] }voice_transplant_paragraphgeneration:runRewrite one paragraph of a chapter to MATCH the voice of another paragraph, or a hand-supplied source passage. Saves a paragraph-scoped chapter_suggestion for review. PAID — charges passage credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "targetChapterId": { "type": "string", "description": "Chapter UUID." }, "targetParagraphIndex": { "type": "integer", "minimum": 0, "description": "0-based paragraph index in the target chapter." }, "sourceChapterId": { "type": "string", "description": "Chapter holding the source paragraph (omit when using sourceText)." }, "sourceParagraphIndex": { "type": "integer", "minimum": 0 }, "sourceText": { "type": "string", "minLength": 20, "description": "Raw source paragraph — overrides sourceChapterId/index." }, "hint": { "type": "string", "maxLength": 300 } }, "required": [ "targetChapterId", "targetParagraphIndex" ] }voice_transplant_passagegeneration:runRewrite a passage in another POV character's voice. The passage is raw text (passageText) or a paragraph range in a chapter (chapterId + fromParagraphIndex + toParagraphIndex). Voice comes from targetCharacterId. Chapter-range mode saves a chapter_suggestion; raw-text mode returns the rewrite unpersisted. PAID — charges passage credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "targetCharacterId": { "type": "string", "description": "book_character id whose voiceProfile to transplant." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "fromParagraphIndex": { "type": "integer", "minimum": 0 }, "toParagraphIndex": { "type": "integer", "minimum": 0 }, "passageText": { "type": "string", "minLength": 20, "maxLength": 8000 }, "hint": { "type": "string", "maxLength": 300 } }, "required": [ "targetCharacterId" ] }regenerate_outline_sectiongeneration:runRe-plan only a contiguous range of chapters (inclusive) — replaces titles + summaries in that range, leaves the rest alone. Refuses to overwrite written or locked chapters unless force: true. PAID — charges outline credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "fromOrder": { "type": "integer", "minimum": 1 }, "toOrder": { "type": "integer", "minimum": 1 }, "directive": { "type": "string", "description": "Optional editorial direction for the new section." }, "force": { "type": "boolean", "description": "Required true if any chapter in range has written prose." } }, "required": [ "bookId", "fromOrder", "toOrder" ] }splice_outline_variantsgeneration:runBuild a composite outline by splicing chapter ranges from the existing outline-variants round. Each pick is {variantId, fromOrder, toOrder}; ranges are stitched in order. Snapshots the prior outline, then replaces UNLOCKED chapters (locked chapters keep their order). DESTRUCTIVE.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "picks": { "type": "array", "minItems": 1, "maxItems": 8, "items": { "type": "object", "properties": { "variantId": { "type": "string" }, "fromOrder": { "type": "integer", "minimum": 1 }, "toOrder": { "type": "integer", "minimum": 1 } }, "required": [ "variantId", "fromOrder", "toOrder" ] } } }, "required": [ "bookId", "picks" ] }generate_scene_cardsgeneration:runDecompose ONE chapter into ordered scene cards (Dwight Swain shape: POV, goal, conflict, disaster, value-shift). Persists into chapters.scenes. Use BEFORE writing the chapter. Refuses to overwrite existing scenes unless overwrite: true. PAID — charges assist credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "order": { "type": "integer", "minimum": 1 }, "overwrite": { "type": "boolean", "description": "Replace existing scene cards. Defaults false." } }, "required": [ "bookId" ] }generate_synopsisgeneration:runGenerate a 1-page (~500–800 word) synopsis of the FULL arc — present tense, third person, ending shown — and store it on the book's synopsis document. Lives separately from the chapter outline. Refuses to overwrite an existing synopsis unless overwrite: true. Needs ≥3 chapters. PAID — charges assist credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "overwrite": { "type": "boolean", "description": "Allow replacing an existing synopsis. Defaults false." } }, "required": [ "bookId" ] }run_premise_stress_testgeneration:runStress-test a premise against four dimensions BEFORE outlining: hook strength, why-now, comp-title resonance, genre fit. Returns 0–100 per dimension plus a hook rewrite, comp titles with scores, suggested genre, and concrete premise revisions. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }generate_marketing_copygeneration:runGenerate launch marketing copy from a finished book: an Amazon-style back-cover blurb, three sample social posts, and a launch announcement email. Pass `kinds` to limit which pieces are generated. Returns the structured payload. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kinds": { "type": "array", "items": { "type": "string", "enum": [ "blurb", "social", "email" ] }, "description": "Which pieces to produce. Defaults to all three." } }, "required": [ "bookId" ] }
Outline & chapter authoring
Generate outlines, write & rewrite chapters, revise ranges, and restructure (split / merge / reorder) with full revision history.
write_chaptergeneration:runGenerate prose for one chapter and persist it. Returns the new content. Streaming is not exposed over MCP — this call resolves when the chapter is fully written and saved. Call chapters in `order` so the writer has continuity. PAID — charges chapter credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }rewrite_chaptergeneration:runApply a directive to revise one chapter (e.g., "punch up the dialogue", "shorten by 30%"). Snapshots the prior text so the change is recoverable, then overwrites the chapter and invalidates audio. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "directive": { "type": "string", "minLength": 3, "description": "Editorial instructions for the rewrite." } }, "required": [ "bookId", "chapterId", "directive" ] }set_chapter_metabooks:writeUpdate a chapter's title, summary, or target word count without touching the prose.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "title": { "type": "string" }, "summary": { "type": [ "string", "null" ] }, "targetWords": { "type": [ "integer", "null" ], "minimum": 0 } }, "required": [ "bookId", "chapterId" ] }reorder_chaptersbooks:writeAtomically reorder chapters. orderedIds must list every chapter id in the new order.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "orderedIds": { "type": "array", "items": { "type": "string" } } }, "required": [ "bookId", "orderedIds" ] }list_chapter_revisionsbooks:readList saved snapshots of a chapter (newest first).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }restore_chapter_revisionbooks:writeRoll a chapter back to a saved snapshot. The current content is snapshotted first, so the restore can itself be undone.
Input schema
{ "type": "object", "properties": { "revisionId": { "type": "string" } }, "required": [ "revisionId" ] }list_chaptersbooks:readList every chapter on a book (id, order, title, summary, word count, audio status, image URL). Dedicated chapter list — pair with `get_chapter` to fetch full prose.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }update_chapterbooks:writeOverwrite a chapter's prose (and optionally its title/summary/notes). Snapshots the prior content so the change is recoverable, resets audio status if the content changed.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "title": { "type": "string", "maxLength": 300 }, "summary": { "type": [ "string", "null" ], "maxLength": 1000 }, "content": { "type": "string", "maxLength": 100000 }, "notes": { "type": [ "string", "null" ], "maxLength": 4000 } }, "required": [ "bookId", "chapterId" ] }split_chapterbooks:writeSplit a chapter into two. Inserts a new (empty) chapter immediately after the original; later chapters' order numbers shift up by 1.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "newTitle": { "type": "string", "minLength": 1 }, "newSummary": { "type": [ "string", "null" ] } }, "required": [ "bookId", "chapterId", "newTitle" ] }merge_chaptersbooks:writeMerge two adjacent chapters into one. The second chapter is removed; its content is appended to the first with a blank line separator. Snapshots both halves first so it's reversible.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "firstChapterId": { "type": "string" }, "secondChapterId": { "type": "string" } }, "required": [ "bookId", "firstChapterId", "secondChapterId" ] }revise_chapter_rangegeneration:runApply one editorial directive consistently across an inclusive range of chapters (e.g. chapters 3–7: tighten pacing, switch to first person). Runs the rewrites in parallel by default — each chapter sees the same pre-rewrite snapshot of its neighbors. Pass parallel: false for one-at-a-time on cost-sensitive runs. Snapshots each chapter before overwriting. PAID — charges 3 rewrite credits per chapter; refunds failed chapters.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "fromOrder": { "type": "integer", "minimum": 1 }, "toOrder": { "type": "integer", "minimum": 1 }, "directive": { "type": "string", "minLength": 3 }, "parallel": { "type": "boolean", "description": "Fan out chapter rewrites concurrently (default true). Each rewrite reads the original pre-rewrite prose of its neighbors." } }, "required": [ "bookId", "fromOrder", "toOrder", "directive" ] }explain_chapter_revisiongeneration:runExplain in plain English why a chapter_revision differs from the chapter's current content. Returns a short TTS-ready narration plus itemized what/why pairs. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "revisionId": { "type": "string", "description": "Chapter revision UUID." } }, "required": [ "revisionId" ] }rewrite_chapter_preservinggeneration:runRewrite a chapter under a directive while keeping specified spans VERBATIM. Pass `preserves` (exact strings) and/or `preserveDialogue: true` to auto-collect quoted dialogue. Saves a chapter_suggestion plus a verification report flagging any preserved span that drifted. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "directive": { "type": "string", "minLength": 3, "maxLength": 800 }, "preserves": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 2000 }, "maxItems": 50 }, "preserveDialogue": { "type": "boolean" } }, "required": [ "chapterId", "directive" ] }reverse_outlinegeneration:runDerive the outline a book ACTUALLY has from its written prose and diff it against the planned outline. Per written chapter: derived summary, beats, POV, setting, plus an alignment verdict (aligned / drifted / off-plan). Pure read. Pass chapterId for a single chapter. PAID — charges critique credits per chapter analysed; refunds failed chapters.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." } }, "required": [ "bookId" ] }check_outline_driftgeneration:runRe-grade the outline and compare to the previously-stored grade so you can see whether the arc on paper has drifted as chapters were drafted. Only re-runs when ≥3 chapters were written since the last grade unless force: true. Run grade_outline once first. PAID — charges critique credits when it re-grades; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "force": { "type": "boolean", "description": "Re-grade even if fewer than 3 new chapters were written." } }, "required": [ "bookId" ] }find_outline_plot_holesgeneration:runScan the FULL outline (every chapter title + summary, plus synopsis if present) for plot holes a structural editor would flag: unresolved setups, unmotivated actions, timeline issues, missing bridges, ability-pops, stake resets. Works on the OUTLINE — fix holes before drafting. Needs ≥5 chapters. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }get_chapter_doc_statebooks:readReport the state of a chapter's rich document — the live editor's layer over the Markdown. Says whether the chapter has been opened in the rich editor, who has it open right now, and whether the Markdown has been rewritten since the editor last caught up. Worth checking before rewriting a chapter wholesale: writes land in the Markdown and an open editor folds them in, but a human may be typing in it. Read-only.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }
Prose analysis
Read-only craft analyzers: filter words, adverb density, sensory balance, concrete nouns, POV slippage, tense consistency, sentence rhythm, dialogue tags, body language, clichés, telegraphing, repetition, style drift, and spoken readability.
lint_prosebooks:readStatic prose linter across one or all chapters — zero LLM cost. Flags adverbs, passive voice, cliches, AI fingerprints, forbidden-word hits, etc. Returns per-chapter severity (green/yellow/red).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }find_repetitionbooks:readDetect overused phrases within a chapter, or repeated sentence openers across the book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "scope": { "type": "string", "enum": [ "chapter", "openers" ] } }, "required": [ "bookId" ] }suggest_cliche_replacementsgeneration:runFind clichés in one chapter and propose specific replacements via the LLM. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }spoken_readabilitybooks:readScore narration difficulty per chapter (consonant clusters, sibilants, breath length, proper nouns).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }style_driftbooks:readMeasure each written chapter's voice fingerprint against the book-wide average. High drift = a chapter is out of voice.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }set_forbidden_wordsbooks:writeSet or clear the per-book forbidden-word list. The linter flags hits and the writer prompt avoids them.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "words": { "type": "array", "items": { "type": "string" } } }, "required": [ "bookId", "words" ] }list_forbidden_wordsbooks:readRead the per-book forbidden-word list.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }set_style_rulesbooks:writeSet or clear the per-book declarative style rules (#67). Each rule is one hard constraint honored across every chapter — 'no semicolons', 'never open a chapter with weather'. Provide `pattern` (a regex source, no slashes/flags, case-insensitive) when the rule is mechanically checkable so the prose-lint pass flags violations; omit it for soft rules. Replaces the existing list — pass the merged set when adding incrementally, or `rules: []` to clear.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "rules": { "type": "array", "maxItems": 50, "description": "Replaces the existing list. Pass [] to clear.", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Stable id for the rule. Omit on new rules and one will be generated." }, "rule": { "type": "string", "description": "Natural-language constraint shown verbatim to the writer." }, "pattern": { "type": [ "string", "null" ], "description": "Optional regex source (no flags) used by the linter to flag violations. Omit for soft rules." }, "scope": { "type": "string", "enum": [ "all", "chapter_open", "chapter_close" ], "description": "'chapter_open' narrows the linter check to the chapter's opening paragraph; 'chapter_close' to the closing. Defaults to 'all'." }, "enabled": { "type": "boolean", "description": "Defaults to true." } }, "required": [ "rule" ] } } }, "required": [ "bookId", "rules" ] }list_style_rulesbooks:readRead the per-book declarative style rules (#67). Returns the rule list and, for any rule carrying a regex pattern, the chapters that currently violate it so targeted rewrites can be proposed. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }analyze_sentence_rhythmbooks:readSentence-rhythm analyzer (#23). Measures sentence-length variance and opener-bucket histograms across a chapter (or every chapter) and flags runs of 4+ similar-length or similar-opener sentences — the AI-prose tell. Zero LLM cost. Returns severity (green/yellow/red) plus the run list.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }find_filter_wordsbooks:readFilter-word stripper (#26). Lists every "she saw / he heard / she noticed" span in a chapter — verbs that filter the reader through the POV character's senses instead of putting them inside the experience. Returns spans with surrounding context. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }analyze_sensory_balancebooks:readSensory-balance audit (#27). Counts cue words per sense (sight, sound, smell, taste, touch, kinesthetic) in a chapter (or every chapter) and flags scenes that are visual-only or missing whole senses. Zero LLM cost. Returns ratios + per-paragraph dominant sense count.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }analyze_adverb_densitybooks:readAdverb-density meter (#28). Reports -ly adverbs per 100 words per chapter, with the genre target band (1–3/100 for tight prose). Lists the actual adverbs sorted by frequency. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }analyze_dialogue_tagsbooks:readDialogue-tag diversifier (#29). Counts "said"/"asked" runs and flags inflated alternatives ("exclaimed", "opined"). Surfaces tag density so rewrites toward beats can be recommended. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }analyze_body_languagebooks:readBody-language vocabulary audit (#30). Counts nod/sigh/shrug/smile/frown/etc. gestures per 1000 words and flags overuse. Zero LLM cost. Helps break the nod-sigh-shrug loop.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }analyze_concrete_nounsbooks:readConcrete-noun ratio (#31). Scores prose 0–100 for concreteness by counting abstract-suffix nouns (-tion, -ity, -ness) and bare-article placeholders against the rest. Zero LLM cost. Flags scenes that float in summary instead of standing on named, physical things.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }check_pov_slippagebooks:readPOV-slippage linter (#34) for strict 1st-person or 3rd-limited. Per-sentence detection — flags any sentence whose dominant pronouns disagree with the chapter's declared POV (or book-level povLock). Zero LLM cost. Returns drift indices the editor can highlight.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "povLock": { "type": "string", "enum": [ "first", "second", "third" ], "description": "Override the book-level povLock for this scan. Useful when one chapter is intentionally a different POV." } }, "required": [ "bookId" ] }check_tense_consistencybooks:readTense-consistency linter (#35). Per-sentence detection of past vs present drift across a chapter (or every chapter). Uses the book-level tenseLock when set, otherwise the chapter's dominant tense. Zero LLM cost. Returns drift indices.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "tenseLock": { "type": "string", "enum": [ "past", "present" ], "description": "Override the book-level tenseLock for this scan." } }, "required": [ "bookId" ] }suggest_cadence_variationsgeneration:runCadence variation suggester (#24). Reads a chapter, finds runs of similar-length sentences, and asks the model for a short+long rewrite that breaks the cadence. Returns the original run and the proposed rewrite. LLM-backed. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }suggest_showing_rewritesgeneration:runShow, don't tell (#25). Reads a chapter, finds abstract emotion words ("she was sad"), and proposes 2–3 embodied rewrites per span — gesture, body-sensation, thought, environmental-cue, or dialogue-beat. LLM-backed. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }detect_semantic_clichesgeneration:runSemantic cliché detector (#32). Asks the model to find paraphrased clichés, dead metaphors, and genre-tired physical reactions in a chapter. Returns verbatim excerpts, a category, why-tired explanation, and a replacement hint. LLM-backed; catches clichés a regex misses. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }detect_telegraphinggeneration:runTelegraphing detector (#33). Reads the whole manuscript and flags foreshadowing heavy enough to give twists away — "little did she know" prose. Each hit names the future beat being leaked, rates severity (soft/medium/heavy), and proposes a softer rewrite. LLM-backed. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }suggest_verb_upgradesgeneration:runVerb-strength upgrader (#36). Reads a chapter, finds weak verb+adverb pairs ("walked quickly") and "to-be + adjective" constructions, and proposes 2–3 strong single-verb replacements per span with connotation labels. LLM-backed. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }
Specialist & critique panel
The round-table: call a specialist, run a critique round-table, skeptic-verify a claim, synthesize as Editor-in-Chief, run a draft tournament, the long-horizon plot doctor, genre-expert lookups, and the debut-reader read.
critique_chaptergeneration:runLLM editorial pass on one written chapter — pacing, voice, continuity, line-level diagnostics. Read-only. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }critique_all_chaptersgeneration:runRun a read-only developmental edit pass on EVERY written chapter (optionally a fromOrder/toOrder range) in parallel. Returns one critique per chapter (pacing, voice drift, continuity). Pure read — no chapter is modified. Pair with revise_chapter_range to act on the findings. PAID — charges 1 critique credit per chapter; refunds failed chapters.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "fromOrder": { "type": "integer", "minimum": 1, "description": "Optional: limit to chapters with order >= fromOrder." }, "toOrder": { "type": "integer", "minimum": 1, "description": "Optional: limit to chapters with order <= toOrder." } }, "required": [ "bookId" ] }list_specialistsbooks:readList the specialist sub-agents available — Dialogue Critic, Pacing Editor, Continuity Hawk, Voice Coach, Plot Doctor, Sensitivity Reader, Line Editor, Marketing Strategist, plus Genre Expert, Debut Reader, Skeptic, and Editor-in-Chief. Returns each key, name, scope, and one-line description.
Input schema
{ "type": "object", "properties": {} }call_specialistgeneration:runRun ONE specialist sub-agent against a chapter (or arbitrary excerpt). Returns a focused critique within that specialist's remit. Use list_specialists to discover keys. Pure read. Pair with editor_in_chief_synthesize when you've collected multiple specialists' findings. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "specialist": { "type": "string", "description": "Specialist key, e.g. 'dialogue-critic', 'pacing-editor', 'continuity-hawk', 'voice-coach', 'plot-doctor', 'sensitivity-reader', 'line-editor', 'marketing-strategist'." }, "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Run against this chapter. Either chapterId or excerpt." }, "excerpt": { "type": "string", "description": "Free-form passage to critique instead of a whole chapter. Provide chapterId OR excerpt." }, "directive": { "type": "string", "description": "Extra instruction to focus the specialist on a specific concern." } }, "required": [ "specialist", "bookId" ] }round_table_critiquegeneration:runFan out N specialist sub-agents in parallel against one chapter and return all their findings. Default panel is the 8 core specialists; override with the specialists array. Pair with editor_in_chief_synthesize to consolidate. PAID — charges 1 critique credit per specialist; refunds failed specialists.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "specialists": { "type": "array", "items": { "type": "string" }, "description": "Optional override: which specialist keys to include. Defaults to the 8 core specialists." }, "directive": { "type": "string", "description": "Extra instruction passed to every specialist." } }, "required": [ "bookId", "chapterId" ] }skeptic_verifygeneration:runAdversarial verify. Take a prior critique and run a skeptic pass that tries to REFUTE every claim. Each finding is labeled STANDS, OVERREACH, or WRONG with a rebuttal. Use to filter out plausible-but-wrong findings before acting. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "The chapter the critique was about. Either chapterId or excerpt." }, "excerpt": { "type": "string" }, "priorCritique": { "type": "string", "description": "The critique to refute — verbatim Markdown body." }, "priorCritiqueAuthor": { "type": "string", "description": "Who produced the critique, e.g. 'Pacing Editor'." } }, "required": [ "bookId", "priorCritique" ] }editor_in_chief_synthesizegeneration:runEditor-in-Chief synthesizer. Take N specialist critiques of the same chapter and consolidate them into ONE prioritized punch list — deduplicating, resolving conflicts, ranking by leverage. Returns the one change that matters most, a numbered punch list, defer items, and resolved disagreements. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "The chapter the critiques refer to. Optional for book-level synthesis." }, "critiques": { "type": "array", "minItems": 2, "description": "At least two specialist critiques to synthesize.", "items": { "type": "object", "properties": { "specialistKey": { "type": "string" }, "specialistName": { "type": "string" }, "findings": { "type": "string" } }, "required": [ "specialistKey", "specialistName", "findings" ] } } }, "required": [ "bookId", "critiques" ] }draft_tournamentgeneration:runN-draft tournament. Generate 2–6 distinct revisions of a passage from different angles (DRAMATIC, INTERIOR, RESTRAINED, LYRICAL, KINETIC, IRONIC), then run a judge that picks a winner with per-draft scoring. Set judgeTier:'deep' for an Opus judge. Never persists. PAID — charges 1 assist credit per draft plus 1 for the judge (3–7); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "passage": { "type": "string", "description": "The passage to revise. Plain prose, no Markdown wrappers." }, "before": { "type": "string", "description": "Optional preceding context for continuity." }, "after": { "type": "string", "description": "Optional trailing context for continuity." }, "n": { "type": "number", "description": "Number of drafts (2–6). Default 3." }, "judgeTier": { "type": "string", "enum": [ "fast", "deep" ], "description": "'fast' (Sonnet, default) or 'deep' (Opus) for the judge." }, "angles": { "type": "array", "items": { "type": "string" }, "description": "Optional angle labels (subset of DRAMATIC, INTERIOR, RESTRAINED, LYRICAL, KINETIC, IRONIC)." } }, "required": [ "bookId", "chapterId", "passage" ] }long_horizon_plot_doctorgeneration:runLong-horizon Plot Doctor. Reads the WHOLE book — outline plus every written chapter — and reports structural issues at the book level: throughline integrity, promise-and-payoff arcs, midpoint pivot, dead chapters, escalation curve, character agency, ending earn. Pure read. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "focus": { "type": "string", "description": "Optional focus, e.g. 'arc of the antagonist' or 'midpoint pivot earned?'." } }, "required": [ "bookId" ] }debut_reader_readgeneration:runDebut Reader simulation. Reads a chapter (or excerpt) as a FIRST-TIME reader who has not seen the outline or any other chapter — reports exactly where a real reader would stumble. Ends with a one-line emotional read. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Read this chapter. Either chapterId or excerpt." }, "excerpt": { "type": "string" } }, "required": [ "bookId" ] }session_reviewgeneration:runEnd-of-session review. Summarises what changed during the writing window (default 24h, max 168) and proposes 3 concrete goals for the next session — based on chapter revisions, open foreshadowing, and unchecked required elements. Read-only. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "windowHours": { "type": "integer", "minimum": 1, "maximum": 168 } }, "required": [ "bookId" ] }
Reader feedback
Test-reader panel, emotional-arc mapping, and hook / ending scoring — see the book the way a first-time reader would.
run_test_reader_panelgeneration:runRun a panel of synthetic test readers (casual, genre fan, literary, skeptical newcomer, tired commuter, editor friend) on one chapter. Each persona reports engagement, confusion moments, emotional beats, and a one-line reaction. Divergence between personas is the signal. PAID — charges 1 critique credit per persona; refunds failed personas.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "personas": { "type": "array", "items": { "type": "string", "enum": [ "casual", "literary", "genre-fan", "skeptical-newcomer", "tired-commuter", "editor-friend" ] }, "description": "Reader personas to include. Defaults to casual + genre-fan + literary + skeptical-newcomer." } }, "required": [ "bookId", "chapterId" ] }analyse_emotional_arcgeneration:runScore the emotional valence and intensity of every paragraph in a chapter and recommend tweaks to the arc shape. Optionally compare against the author's INTENDED arc to surface gaps between intended and felt. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "intendedArc": { "type": "string", "description": "Short prose: \"starts grief-heavy, lifts to bitter hope by the close\"." } }, "required": [ "bookId", "chapterId" ] }score_hook_strengthgeneration:runScore the opening of a chapter at four nested scopes — first sentence, first paragraph, first scene, first chapter — with a comp-aware verdict and the single highest-leverage edit. Defaults to the lowest-order chapter (the book opening) when no chapterId is given. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "compTitles": { "type": "string", "description": "Comma-separated comp titles to anchor the comp note." } }, "required": [ "bookId" ] }predict_ending_satisfactiongeneration:runCompare the PROMISES the first chapter makes against the DELIVERY in the last chapter and surface any gap that would leave a reader unsatisfied. Both first and last chapters must be written. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "intendedClosingFeeling": { "type": "string", "description": "Optional author intent — e.g. \"exhausted but quietly hopeful\"." } }, "required": [ "bookId" ] }confused_reader_reviewgeneration:runRead one chapter cold, as a first-time reader who has not read the rest of the book, and report exactly where you got lost. Read-only — nothing is modified. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "directive": { "type": "string", "maxLength": 400, "description": "Optional reader profile." } }, "required": [ "chapterId" ] }list_webhooksbooks:readList this account's registered webhook endpoints, their subscribed events, and recent delivery health (last status, consecutive failures, whether auto-disabled).
Input schema
{ "type": "object", "properties": {} }create_webhookbooks:writeRegister a webhook endpoint. Anthra POSTs a signed JSON event to `url` whenever one of the subscribed `events` occurs, so you can stop polling. Returns a signing secret ONCE — store it; verify deliveries with the `anthra-signature` header. Use `["*"]` to subscribe to all events.
Input schema
{ "type": "object", "properties": { "url": { "type": "string", "description": "HTTPS endpoint that receives POSTed events. Must be a public host." }, "events": { "type": "array", "items": { "type": "string" }, "description": "Event names to subscribe to. One or more of: job.succeeded, job.failed, book.published, book.unpublished. Or [\"*\"] for all." }, "description": { "type": "string", "description": "Optional label for the dashboard." } }, "required": [ "url", "events" ] }delete_webhookbooks:writeDelete a webhook endpoint by id. Deliveries stop immediately.
Input schema
{ "type": "object", "properties": { "webhookId": { "type": "string" } }, "required": [ "webhookId" ] }ping_webhookbooks:writeSend a synthetic `job.succeeded` test event to your registered endpoints so you can confirm signature verification and connectivity before relying on real events.
Input schema
{ "type": "object", "properties": {} }
Worldbuilding & continuity
World rules, timeline / geography / weather / travel-time checks, unit consistency, invented terms & calendars, the foreshadowing ledger, object & location trackers, scene consistency, and continuity diffs.
check_continuitygeneration:runRun a continuity check across the whole book. Flags cross-chapter inconsistencies (names, dates, prop placement, motivation). PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }add_world_rulebooks:writeRegister a rule of the book's world (#37). Pair with scan_world_rule_violations to flag chapters that contradict the rule.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "name": { "type": "string" }, "category": { "type": "string", "enum": [ "magic", "tech", "social", "physics", "economy", "religion", "other" ], "default": "other" }, "rule": { "type": "string" }, "examples": { "type": "array", "items": { "type": "string" }, "default": [] }, "severity": { "type": "string", "enum": [ "hard", "soft" ], "default": "hard" } }, "required": [ "bookId", "name", "rule" ] }list_world_rulesbooks:readList every world rule registered for a book (#37) plus open-violation counts.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }update_world_rulebooks:writeUpdate a world rule (#37). Pass only fields you want to change.
Input schema
{ "type": "object", "properties": { "ruleId": { "type": "string", "description": "World-rule UUID." }, "name": { "type": "string" }, "category": { "type": "string", "enum": [ "magic", "tech", "social", "physics", "economy", "religion", "other" ] }, "rule": { "type": "string" }, "examples": { "type": "array", "items": { "type": "string" } }, "severity": { "type": "string", "enum": [ "hard", "soft" ] } }, "required": [ "ruleId" ] }delete_world_rulebooks:writeDelete a world rule (#37) and cascade its violation rows.
Input schema
{ "type": "object", "properties": { "ruleId": { "type": "string" } }, "required": [ "ruleId" ] }scan_world_rule_violationsgeneration:runScan one chapter (or every written chapter) for places the prose violates a registered world rule (#37). Wipes prior violation rows for the touched chapters before re-inserting. Costs LLM tokens. PAID: charges the critique rate × manuscript size (1 credit per ~25k words scanned, min 1 — ~4–5 for a typical novel); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string", "description": "Limit to one chapter (optional)." } }, "required": [ "bookId" ] }list_world_rule_violationsbooks:readList currently-open world-rule violations across a book (#37).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "includeDismissed": { "type": "boolean", "default": false } }, "required": [ "bookId" ] }dismiss_world_rule_violationbooks:writeDismiss a world-rule violation flag (#37) — marks it intentional.
Input schema
{ "type": "object", "properties": { "violationId": { "type": "string" } }, "required": [ "violationId" ] }refresh_timeline_calendargeneration:runAuto-extract dated/sequenced events with calendar metadata — day-of-week, time-of-day, story-day counter, optional date label — for one chapter or every written chapter (#38). Wipes prior events for the touched chapters before re-inserting. Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }get_story_calendarbooks:readReturn the book's timeline grouped as a calendar (#38) — story days, day-of-week, time-of-day buckets — under the invented calendar config when one exists, otherwise Gregorian. Read-only.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }refresh_geography_graphgeneration:runRe-derive the geography graph (#39) from the book's registered places + the prose. Inserts rows in book_geography_edge with distances and travel times the prose anchors. Costs LLM tokens. PAID: charges the assist rate × manuscript size (1 credit per ~25k words scanned, min 1 — ~4–5 for a typical novel); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "replace": { "type": "boolean", "default": false } }, "required": [ "bookId" ] }list_geography_edgesbooks:readList every registered geography edge for a book (#39). Read-only.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }refresh_weathergeneration:runAuto-extract season / weather / temperature / precipitation / time-of-day for one chapter (or every written chapter) and upsert into book_chapter_weather (#41). Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }check_weather_continuitybooks:readWalk book_chapter_weather chapter-by-chapter (#41) and surface season jumps that don't fit the day-of-story gap plus same-day weather contradictions. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }check_travel_sanitybooks:readWalk the geography graph + the timeline (#42) and surface chapters where a character covers a registered route faster than its travel time should allow. refresh_geography_graph and refresh_timeline_calendar must be up-to-date. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "tolerancePct": { "type": "number", "minimum": 0, "maximum": 100, "default": 20 } }, "required": [ "bookId" ] }register_unitbooks:writeRegister a canonical unit / currency / language for the book (#43). Multiple canonicals per kind ARE allowed. Re-registering the same canonical for the same kind updates its aliases instead of inserting a duplicate. Use remove_unit to drop a canonical the prose no longer needs.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kind": { "type": "string", "enum": [ "currency", "distance", "time", "temperature", "weight", "volume", "language", "other" ] }, "canonical": { "type": "string" }, "aliases": { "type": "array", "items": { "type": "string" }, "default": [] }, "note": { "type": "string" } }, "required": [ "bookId", "kind", "canonical" ] }list_unitsbooks:readList every registered unit / currency / language for a book (#43).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }remove_unitbooks:writeDelete a registered unit (#43).
Input schema
{ "type": "object", "properties": { "unitId": { "type": "string" } }, "required": [ "unitId" ] }scan_unit_driftgeneration:runScan the manuscript for places the prose uses a unit / currency / language that conflicts with the registry (#43). Read-only. Costs LLM tokens proportional to manuscript size. PAID: charges the critique rate × manuscript size (1 credit per ~25k words scanned, min 1 — ~4–5 for a typical novel); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }add_invented_termbooks:writeRegister an invented term (custom / holiday / slang / general world-term) (#44). Adds a row to book_world_term so it shares the existing glossary surface.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "name": { "type": "string" }, "category": { "type": "string", "enum": [ "custom", "holiday", "slang", "term" ], "default": "term" }, "definition": { "type": "string" }, "aliases": { "type": "array", "items": { "type": "string" }, "default": [] } }, "required": [ "bookId", "name", "definition" ] }list_invented_termsbooks:readList invented terms registered for a book — customs, holidays, slang, general world terms (#44). Returns each term plus its in-prose mention count.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kind": { "type": "string", "enum": [ "custom", "holiday", "slang", "term" ] } }, "required": [ "bookId" ] }refresh_invented_termsgeneration:runAuto-extract invented terms (customs, holidays, slang) from one chapter (or every written chapter) and log each usage to book_world_term_mention (#44). Terms not yet in book_world_term get inserted. Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }scan_invented_term_contradictionsgeneration:runDiff per-chapter mentions of an invented term and surface places the prose's definition contradicts the canonical or itself across chapters (#44). Pass termId to focus one; omit to scan every invented term. Costs LLM tokens per term. PAID: charges 1 credit (critique) per term scanned; terms with fewer than two mentions are refunded, as is any failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "termId": { "type": "string" } }, "required": [ "bookId" ] }get_invented_calendarbooks:readRead the saved invented calendar for a book (#45). Null if none saved.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }set_invented_calendarbooks:writeSave a complete invented calendar config for the book (#45). Replaces any existing config. `yearLengthDays` is recomputed from `months[].days` server-side.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "name": { "type": "string", "default": "Invented calendar" }, "eraName": { "type": [ "string", "null" ] }, "hoursPerDay": { "type": "integer", "minimum": 1, "maximum": 72, "default": 24 }, "daysPerWeek": { "type": "integer", "minimum": 1, "maximum": 20, "default": 7 }, "dayNames": { "type": "array", "items": { "type": "string" } }, "months": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "days": { "type": "integer", "minimum": 1, "maximum": 60 }, "season": { "type": [ "string", "null" ] } }, "required": [ "name", "days" ] } }, "festivals": { "type": "array", "default": [], "items": { "type": "object", "properties": { "name": { "type": "string" }, "month": { "type": "integer", "minimum": 1 }, "day": { "type": "integer", "minimum": 1 }, "description": { "type": [ "string", "null" ] } }, "required": [ "name", "month", "day" ] } } }, "required": [ "bookId", "dayNames", "months" ] }continuity_diffgeneration:runWhen a chapter was rewritten, check whether later chapters now reference facts the new version removed (#46). Compares the latest chapter_revisions snapshot to the current prose, computes which canonical facts are gone, then scans later chapters for references to them. Costs LLM tokens. PAID: charges the critique rate for 3 model calls — the two fact extractions plus the later-chapter scan — each × its text size (1 credit per ~25k words, min 1); refunds the scan's share when it isn't needed, and everything on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }register_foreshadowingbooks:writeRegister a foreshadowing setup (#86). The author flags a planted moment; the tracker stays 'open' until mark_foreshadowing_paid is called. Optional thread tag groups related setups.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "setupChapterId": { "type": "string", "description": "Chapter where the setup is planted." }, "setup": { "type": "string", "description": "Short description of what was set up (3-280 chars)." }, "thread": { "type": "string", "description": "Optional thread tag (max 60 chars)." }, "importance": { "type": "string", "enum": [ "critical", "important", "cosmetic" ], "description": "Defaults to \"important\"." } }, "required": [ "bookId", "setupChapterId", "setup" ] }mark_foreshadowing_paidbooks:writeMark a registered foreshadowing setup as paid off (#86). Provide the payoff chapter id and a one-line payoff description. Use status='dropped' instead when the author has decided not to pay it off.
Input schema
{ "type": "object", "properties": { "foreshadowingId": { "type": "string" }, "paidOffChapterId": { "type": "string" }, "payoff": { "type": "string", "description": "One-line payoff description (max 280 chars)." }, "status": { "type": "string", "enum": [ "paid", "dropped" ], "description": "Defaults to \"paid\"." } }, "required": [ "foreshadowingId" ] }list_unpaid_foreshadowingbooks:readList every open (unpaid) foreshadowing setup for a book (#86). Each row includes the setup chapter order and how many chapters have passed since. Read-only.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "importanceMin": { "type": "string", "enum": [ "critical", "important", "cosmetic" ], "description": "Filter by minimum importance. Defaults to all." } }, "required": [ "bookId" ] }did_anyone_say_this_earliergeneration:runSemantic search across the whole book (#97): did anyone — narrator or character — say something like this earlier? Returns near-quotes, paraphrases, and thematic echoes with chapter + paragraph anchors. Two-stage: a free token-overlap shortlist then an LLM refinement, so a query with no candidates costs zero LLM tokens. PAID: charges 1 credit (assist) when the shortlist reaches the LLM; refunded otherwise or on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "query": { "type": "string", "description": "The line, phrase, or idea to look for (3-600 chars)." }, "beforeChapterId": { "type": "string", "description": "Optional: only search chapters that come before this one." } }, "required": [ "bookId", "query" ] }check_scene_consistencygeneration:runFocused continuity check on three high-value axes only — time-of-day flips, weather contradictions, and travel times that don't fit (#96). Returns structured, per-chapter flags. Costs LLM tokens proportional to manuscript size. PAID: charges 1 credit (critique); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }check_pronoun_continuitygeneration:runScan one chapter or all chapters for pronoun drift, roster mismatch, or unresolved pronouns (#22). Uses each character's declared pronouns as the source of truth. Costs LLM tokens proportional to prose scanned. PAID: charges 1 credit (critique); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }refresh_object_trackergeneration:runAuto-extract tracked objects / MacGuffins from one chapter (or every written chapter) and write to book_object + book_object_state (#94). Each object's per-chapter state is rebuilt for the touched chapters so the trail stays in sync with the prose. Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }list_object_trailbooks:readReturn every tracked object's per-chapter state trail (#94) — where it is, who holds it, what happened — sorted by chapter order. Read-only.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "objectName": { "type": "string", "description": "Optional: filter to a single named object (matches name or alias)." } }, "required": [ "bookId" ] }refresh_timelinegeneration:runAuto-extract dated / sequenced story events from one chapter (or every written chapter) and rebuild book_timeline_event (#93). Wipes the chapter's prior events before re-inserting. Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }refresh_location_dbgeneration:runAuto-extract places from one chapter (or every written chapter) and merge them into book_world_term with kind='place' (#92). Captures lat/lng when the prose grounds the place to a real-world coordinate, and an ASCII floor plan when the interior is described in enough detail. Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }set_chapter_checklistbooks:writeSet the per-chapter required-element checklist. Each item is a named beat the chapter must hit (callback / setup / payoff / beat / other). Replaces the existing list. Pass done: true for satisfied items, or an empty array to clear.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "items": { "type": "array", "maxItems": 20, "items": { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "callback", "setup", "payoff", "beat", "other" ] }, "text": { "type": "string", "minLength": 2, "maxLength": 280 }, "done": { "type": "boolean" } }, "required": [ "kind", "text" ] } } }, "required": [ "chapterId", "items" ] }auto_check_checklistgeneration:runVerify each item on a chapter's required-element checklist against the current prose using the model. Marks done=true with a one-line note when present; leaves unconfirmed items untouched. Read-only on the prose; mutates only the checklist column. PAID — charges assist credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." } }, "required": [ "chapterId" ] }
Character craft
Character roster (want / fear / lie), inter-character conflicts, dialogue fingerprints, per-character voice consistency, and character arcs.
list_charactersbooks:readList the book's characters with the Truby-style want/fear/lie axes, POV flag, voice profile, and aliases.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }create_characterbooks:writeCreate a character row with name + optional want/fear/lie planning axes, voice profile, bio, role, aliases, and POV flag.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "name": { "type": "string" }, "aliases": { "type": "array", "items": { "type": "string" } }, "role": { "type": [ "string", "null" ] }, "bio": { "type": [ "string", "null" ] }, "voiceProfile": { "type": [ "string", "null" ] }, "want": { "type": [ "string", "null" ] }, "fear": { "type": [ "string", "null" ] }, "lie": { "type": [ "string", "null" ] }, "isPov": { "type": "boolean" } }, "required": [ "bookId", "name" ] }update_characterbooks:writePatch a character. Pass any subset of fields. Set want/fear/lie to null to clear those axes.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" }, "name": { "type": "string" }, "aliases": { "type": "array", "items": { "type": "string" } }, "role": { "type": [ "string", "null" ] }, "bio": { "type": [ "string", "null" ] }, "voiceProfile": { "type": [ "string", "null" ] }, "want": { "type": [ "string", "null" ] }, "fear": { "type": [ "string", "null" ] }, "lie": { "type": [ "string", "null" ] }, "isPov": { "type": "boolean" } }, "required": [ "bookId", "characterId" ] }delete_characterbooks:writeRemove a character row. Conflict edges cascade.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" } }, "required": [ "bookId", "characterId" ] }list_character_conflictsbooks:readList the inter-character conflict matrix. Each row is 'from <kind> to' — e.g. 'Marin blocks Alex'.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }add_character_conflictbooks:writeAdd a conflict edge. Kind: blocks, rivals, loves, fears, manipulates, protects, betrays, other.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "fromCharacterId": { "type": "string" }, "toCharacterId": { "type": "string" }, "kind": { "type": "string", "enum": [ "blocks", "rivals", "loves", "fears", "manipulates", "protects", "betrays", "other" ] }, "description": { "type": [ "string", "null" ] } }, "required": [ "bookId", "fromCharacterId", "toCharacterId", "kind" ] }remove_character_conflictbooks:writeRemove one conflict edge.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "conflictId": { "type": "string" } }, "required": [ "bookId", "conflictId" ] }refresh_character_dbgeneration:runRe-run the structured character extractor against one written chapter (or every written chapter) and MERGE the findings into the book's character DB (#91). Existing rows pick up newly-revealed details (voiceProfile, bio); new names become new rows; aliases are unioned. Updates lastSeenChapterOrder. Costs LLM tokens per chapter. PAID: charges 1 credit (assist) per chapter scanned; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Optional: process just this chapter. Otherwise every written chapter." } }, "required": [ "bookId" ] }extract_dialogue_fingerprintsgeneration:runAuto-extract a per-character dialogue fingerprint (#11) — lexicon, average sentence length, hedges, contraction rate, signature phrases — and persist to book_character.dialogueFingerprint. Pass characterId to scope to one character; full-roster runs are capped at 12 per call (call again with characterId for any skipped). Costs LLM tokens per character. PAID: charges 1 credit (assist) per character; refunds failed characters / on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" } }, "required": [ "bookId" ] }check_dialogue_voice_consistencygeneration:runScan one chapter's dialogue for lines that sound like the wrong character (#12), using each cast member's stored dialogue fingerprint. Run extract_dialogue_fingerprints first so fingerprints exist. Costs LLM tokens proportional to chapter size. PAID: charges 1 credit (critique); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }track_character_arcsgeneration:runAnalyse one or all characters' four-axis arc — want / need / lie / truth — and per-chapter movement, then persist need/truth + arcMovements (#13). Pass characterId to scope; full-roster runs are capped at 12 per call. Costs LLM tokens proportional to manuscript size × characters analysed. PAID: charges 1 credit (critique) per character; refunds failed characters / on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" } }, "required": [ "bookId" ] }detect_minor_character_bloatbooks:readFind named roster characters who appear ≤ maxAppearances times in written chapters (#18) — default threshold 1 (one-off mentions). Counts case-insensitive occurrences of each character's name + aliases. Pure heuristic — no LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "maxAppearances": { "type": "number", "description": "Default 1 (1-10)." } }, "required": [ "bookId" ] }check_character_registergeneration:runFlag dialogue lines where a character drifts out of their declared class / cultural / regional register (#21). Requires bookCharacters.register to be set on the targeted characters; full-roster runs are capped at 12 per call. Costs LLM tokens proportional to prose scanned × characters checked. PAID: charges 1 credit (critique) per character; refunds failed characters / on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" } }, "required": [ "bookId" ] }
Persona & structural editing
Track-changes edits, editor personas, sentence variants, tense / POV flips, voice transplant, cut-by-percent, expand, reverse-outline, scene cards, synopsis, and the reviewable suggestion queue.
edit_chapter_with_personageneration:runRun one editor persona over a chapter and save the result as a REVIEWABLE pending chapter_suggestion — never an overwrite. Returns the new suggestionId plus a plain-English summary. Apply with accept_chapter_suggestion or dismiss with reject_chapter_suggestion. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "personaKey": { "type": "string", "description": "Built-in key (developmental / line / copy / structural-only / wording-only …) or a user-saved persona key." }, "directive": { "type": "string", "maxLength": 800, "description": "Optional one-line editorial note layered on top of the persona's remit." } }, "required": [ "chapterId", "personaKey" ] }edit_book_with_personageneration:runApply one editor persona across a range of chapters (default whole book), producing one REVIEWABLE pending chapter_suggestion per chapter. Returns per-chapter suggestionIds + summaries. Accept or reject each independently. PAID — charges rewrite credits per chapter in range; refunds failed chapters.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "personaKey": { "type": "string" }, "directive": { "type": "string", "maxLength": 800 }, "fromOrder": { "type": "integer", "minimum": 1 }, "toOrder": { "type": "integer", "minimum": 1 } }, "required": [ "bookId", "personaKey" ] }list_chapter_suggestionsbooks:readList pending (and optionally decided) chapter_suggestion rows for a book or a single chapter. Returns persona key, summary, and metadata — not the full proposed prose.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "includeDecided": { "type": "boolean" } }, "required": [ "bookId" ] }get_chapter_suggestionbooks:readRead the full proposed content of one chapter_suggestion (plus persona, summary, current content, metadata). Use to inspect the diff before accepting.
Input schema
{ "type": "object", "properties": { "suggestionId": { "type": "string", "description": "Suggestion UUID." } }, "required": [ "suggestionId" ] }accept_chapter_suggestionbooks:writeApply a pending chapter_suggestion — atomically snapshots current content (undoable via restore_chapter_revision) and overwrites with proposedContent. Re-accepting a decided suggestion is a no-op error.
Input schema
{ "type": "object", "properties": { "suggestionId": { "type": "string", "description": "Suggestion UUID." } }, "required": [ "suggestionId" ] }reject_chapter_suggestionbooks:writeReject a pending chapter_suggestion without applying it. Re-rejecting a decided suggestion is a no-op error.
Input schema
{ "type": "object", "properties": { "suggestionId": { "type": "string", "description": "Suggestion UUID." } }, "required": [ "suggestionId" ] }narrate_chapter_diffgeneration:runRead the CHANGES (not the new prose) of a chapter_revision aloud — synthesizes audio of a plain-English diff walkthrough, stores it in blob, and returns the audio URL plus the spoken text. PAID — charges critique credits for the diff summary plus TTS credits per ~1k characters spoken; refunds on failure.
Input schema
{ "type": "object", "properties": { "revisionId": { "type": "string", "description": "Chapter revision UUID." } }, "required": [ "revisionId" ] }comment_chaptergeneration:runLeave paragraph-anchored margin notes on a chapter — praise / note / concern / question — without touching the prose. Read-only; nothing is persisted. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "focus": { "type": "string", "maxLength": 400, "description": "Optional focus area." } }, "required": [ "chapterId" ] }append_paragraph_to_chapterbooks:writeAppend a paragraph to a chapter's prose (Markdown). Snapshots existing content first (undoable via restore_chapter_revision) and keeps word-count / reading-time in sync.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "paragraph": { "type": "string", "minLength": 1 } }, "required": [ "chapterId", "paragraph" ] }track_changes_editgeneration:runRun an editorial directive over a chapter and return the result as accept/reject HUNKS. Persists a chapter_suggestion with the full proposed prose; the response includes a paragraph diff with per-hunk indices for accept_suggestion_hunks. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "directive": { "type": "string", "minLength": 3, "maxLength": 800 }, "personaKey": { "type": "string", "description": "Optional persona to drive the edit. Defaults to a line-edit pass." } }, "required": [ "chapterId", "directive" ] }accept_suggestion_hunksbooks:writeApply only chosen hunks from a track-changes chapter_suggestion. Diffs the suggestion against the chapter CURRENT content, rebuilds using original paragraphs for un-chosen hunks and proposed paragraphs for chosen ones. Snapshots first (undoable). Marks the suggestion accepted.
Input schema
{ "type": "object", "properties": { "suggestionId": { "type": "string", "description": "Suggestion UUID." }, "hunkIndices": { "type": "array", "items": { "type": "integer", "minimum": 0 }, "minItems": 1, "description": "0-based indices into the hunks array from track_changes_edit." } }, "required": [ "suggestionId", "hunkIndices" ] }sentence_variantsgeneration:runGenerate N labeled variants of a single sentence with named tradeoffs (tighter / lyrical / clipped / warmer / colder by default). Read-only — nothing is saved. Anchor with chapterId + paragraphIndex, or pass contextText. PAID — charges passage credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "sentence": { "type": "string", "minLength": 3, "maxLength": 800 }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "paragraphIndex": { "type": "integer", "minimum": 0 }, "contextText": { "type": "string", "maxLength": 2000 }, "voiceHint": { "type": "string", "maxLength": 280 }, "variantStyles": { "type": "array", "items": { "type": "string", "minLength": 2, "maxLength": 40 }, "minItems": 1, "maxItems": 8 } }, "required": [ "sentence" ] }cut_chapter_by_percentgeneration:runTighten a chapter by ~N% — every fact, beat, and dialogue line is preserved; only fat is removed. Saves a chapter_suggestion plus a paragraph diff preview. Default cut is 15%. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "cutPercent": { "type": "integer", "minimum": 1, "maximum": 60, "description": "Percent of word count to cut. Defaults to 15." } }, "required": [ "chapterId" ] }expand_sentencegeneration:runExpand a sentence (or short seed) into a paragraph in the established voice. Read-only — nothing is persisted. Pass chapterId to pick up book voice + style bible; paragraphIndex to inject surrounding context. PAID — charges passage credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "sentence": { "type": "string", "minLength": 3, "maxLength": 2000 }, "chapterId": { "type": "string", "description": "Chapter UUID." }, "paragraphIndex": { "type": "integer", "minimum": 0 }, "voiceHint": { "type": "string", "maxLength": 400 } }, "required": [ "sentence" ] }flip_chapter_tensegeneration:runFlip a chapter's narration past↔present. Dialogue is left untouched. Returns a chapter_suggestion plus a change log. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "targetTense": { "type": "string", "enum": [ "past", "present" ] } }, "required": [ "chapterId", "targetTense" ] }shift_chapter_povgeneration:runShift a chapter's POV (typically third-limited ↔ first-person). Pass fromPov, toPov, optionally povCharacterId. Returns a chapter_suggestion plus the list of required changes the shift forced. PAID — charges rewrite credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "fromPov": { "type": "string", "minLength": 3, "maxLength": 80 }, "toPov": { "type": "string", "minLength": 3, "maxLength": 80 }, "povCharacterId": { "type": "string" } }, "required": [ "chapterId", "fromPov", "toPov" ] }
Scorecards, eval & ideation
Quality scorecards, eval exemplars, and the ideas inbox (capture / organise / triage).
list_chapter_scorecardsbooks:readList historical scorecards for a chapter (newest first) so the author can see how rewrites moved the grade.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." } }, "required": [ "chapterId" ] }list_book_scorecardsbooks:readList the latest scorecard per chapter for a book so the author can scan grade variance across the manuscript.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }list_eval_exemplarsbooks:readList the author's registered voice exemplars. Optional bookId narrows to exemplars tied to that book; catalog-wide exemplars (bookId=null) always appear.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } } }add_eval_exemplarbooks:writeRegister a passage as 'this is what good looks like in MY voice'. The eval pass silently scores new drafts against these. Pass bookId to scope to one book; omit to make it catalog-wide.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "label": { "type": "string", "description": "Short label (1–200 chars)." }, "content": { "type": "string", "description": "Exemplar prose (80–8000 chars)." }, "notes": { "type": "string" } }, "required": [ "label", "content" ] }remove_eval_exemplarbooks:writeDelete one of the author's voice exemplars.
Input schema
{ "type": "object", "properties": { "id": { "type": "string", "description": "Exemplar UUID." } }, "required": [ "id" ] }evaluate_against_exemplarsgeneration:runScore a draft against the author's registered exemplars and return the closest match plus per-exemplar voice / prose-quality scores. Use after a rewrite or before publishing to confirm voice hasn't drifted. PAID — charges 1 assist credit per exemplar compared; refunds failed comparisons.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "If supplied, the chapter's content is used as the draft." }, "draft": { "type": "string", "description": "Free-form draft to score; required when chapterId is omitted." }, "maxExemplars": { "type": "number", "description": "Max exemplars to compare (1–12). Default 6." } } }capture_ideabooks:writeDrop a fragment into the book's idea inbox — a line of dialogue, a stray image, a reminder. Files it without writing prose. Optionally tag it or assign it to a chapter; otherwise it sits in the inbox until organise_ideas runs.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "body": { "type": "string", "minLength": 2, "maxLength": 2000 }, "source": { "type": "string", "maxLength": 40 }, "targetChapterId": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" }, "maxItems": 8 } }, "required": [ "bookId", "body" ] }list_ideasbooks:readList captured ideas for a book. Defaults to the live (inbox + assigned) ideas; pass `status` to filter, or `chapterId` to scope to one chapter.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "status": { "type": "string", "enum": [ "inbox", "assigned", "applied", "archived", "all" ] }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }organise_ideasgeneration:runRead every inbox idea and assign each to the chapter it best fits, using the outline + chapter summaries. Sets targetChapterId and status='assigned' — does NOT write prose into chapters. The author still applies the lines by hand. PAID — charges 1 assist credit when the inbox is non-empty; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }update_idea_statusbooks:writeMove an idea to a new status — 'applied' when the line landed in a chapter, 'archived' when the author cuts it.
Input schema
{ "type": "object", "properties": { "ideaId": { "type": "string" }, "status": { "type": "string", "enum": [ "inbox", "assigned", "applied", "archived" ] } }, "required": [ "ideaId", "status" ] }
Cover, illustration & production
Choose a cover color, generate cover / back-cover / spine / chapter art, compose the print-ready wraparound, set the page layout (platform profile, trim size, bleed, margins, typography), render EPUB / DOCX / PDF, export Markdown, and estimate print cost.
get_production_job_statusanalytics:readPoll a production (PDF/audiobook) job by id.
Input schema
{ "type": "object", "properties": { "jobId": { "type": "string" } }, "required": [ "jobId" ] }choose_cover_colorgeneration:runPick a tasteful cover background color (6-digit hex) for a book based on its mood, genre, and tone, and save it. Cheap LLM call — PAID, charges one assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "mood": { "type": "string", "description": "Optional mood hint (e.g. \"stormy\", \"warm and hopeful\")." } }, "required": [ "bookId" ] }compose_cover_spreadgeneration:runCompose the existing front cover, spine, and back cover into one print-ready wraparound spread (PNG). Uploads to Vercel Blob and records as a `cover_spread` image. Requires all three panels to exist already (run `generate_cover_art`, `generate_back_cover`, `generate_spine` first).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }get_cover_setupbooks:readA book's cover setup: trim size, paper, page count (and whether estimated), the exact print wrap / spine / bleed in inches, whether spine text fits, which art exists, and the available sizes, layouts and fonts.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }set_cover_settingsbooks:writeSet the book size (trimPresetId), paper (white | cream | color) and/or interior page count (24–828; null = estimate from word count) the covers are built for. Sets the spine width; the trim also applies to the interior layout.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "trimPresetId": { "type": "string", "enum": [ "pocket", "5x8", "5.25x8", "5.5x8.5", "6x9", "7x10", "8x10", "8.5x11", "11x11", "12x12", "a4" ] }, "paper": { "type": "string", "enum": [ "white", "cream", "color" ] }, "pageCount": { "type": [ "integer", "null" ], "minimum": 24, "maximum": 828 } }, "required": [ "bookId" ] }style_cover_textbooks:writeSet the cover text: title / author / blurb wording, a front layout preset, title font, text colour (#rrggbb), or reset to defaults. Covers carry the title, author and blurb by default, so this is only for changes.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "title": { "type": "string", "maxLength": 200 }, "author": { "type": "string", "maxLength": 120 }, "blurb": { "type": "string", "maxLength": 1500 }, "layout": { "type": "string", "enum": [ "classic-top", "centered", "lower-banner", "left-stack", "script-hero" ] }, "font": { "type": "string", "enum": [ "serif", "sans", "script" ] }, "color": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" }, "reset": { "type": "boolean" } }, "required": [ "bookId" ] }export_coversbooks:readRender the finished cover files and return URLs: the 1600 × 2560 ebook cover PNG and/or the print-ready wraparound PDF (back + spine + front, 0.125" bleed) at the book size, paper and page count — upload-ready for KDP and IngramSpark. which: ebook | print | both (default).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "which": { "type": "string", "enum": [ "ebook", "print", "both" ] } }, "required": [ "bookId" ] }export_book_markdownbooks:readExport a fully written book as a single Markdown file, uploaded to Vercel Blob; returns a public download URL.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }produce_bookgeneration:runRender a fully written book to EPUB / DOCX (synchronous — bytes returned via blob URL) or PDF (async — dispatches a workflow job, returns jobId; poll with `get_production_job_status`).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "format": { "type": "string", "enum": [ "epub", "docx", "pdf" ] } }, "required": [ "bookId", "format" ] }list_print_productsbooks:readList every Lulu print-on-demand product available on this instance (key, label, trim, cover finish, page-count bounds). Use the key with `get_print_estimate`.
Input schema
{ "type": "object", "properties": {} }get_print_estimateanalytics:readGet a retail print-on-demand quote from Lulu for the book with the chosen product, quantity, shipping option, and destination address. Read-only — no order is placed. Page count is estimated from word count; the real value may shift by a few pages after `produce_book` runs the PDF render.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "productKey": { "type": "string", "description": "A key from `list_print_products` (e.g. \"paperback-6x9-bw\")." }, "quantity": { "type": "integer", "minimum": 1, "maximum": 500 }, "shippingLevel": { "type": "string", "enum": [ "MAIL", "PRIORITY_MAIL", "GROUND", "EXPEDITED", "EXPRESS" ] }, "shippingAddress": { "type": "object", "description": "Lulu-style address (name, street1, city, state_code, postcode, country_code, …)." } }, "required": [ "bookId", "productKey", "quantity", "shippingLevel", "shippingAddress" ] }list_print_ordersbooks:readList physical print-on-demand orders for this account (or a single book with `bookId`): status, product, quantity, page count, charge, tracking, and timestamps. Placing an order still happens in the Publish → Print UI (it charges real money and needs a validated shipping address); this tool tracks orders after the fact.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } } }get_print_orderbooks:readFetch one print order by id, refreshing its status from Lulu first so tracking and fulfillment state are current.
Input schema
{ "type": "object", "properties": { "orderId": { "type": "string" } }, "required": [ "orderId" ] }cancel_print_orderbooks:writeRequest cancellation of a print order that has not yet entered production. Fails if the order already shipped or is past the cancellable window.
Input schema
{ "type": "object", "properties": { "orderId": { "type": "string" } }, "required": [ "orderId" ] }list_trim_sizesbooks:readList every print trim size Anthra can produce, grouped by category (paperback & trade, large & coffee-table, screen & international). Pass `bookId` to also get that book's current layout: platform profile, trim, bleed, inner margin, estimated page count, and the inner margin the platform spec requires at that length. Read-only — change the layout with `set_manuscript_config`.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Optional — include to report this book's layout." } } }set_manuscript_configbooks:writeSet how a book is laid out for print and export: platform profile (kdp-paperback, kdp-hardcover, ingramspark, lulu, custom), trim size (a preset id from `list_trim_sizes` or a custom width/height), bleed, margins, typography, front matter, running headers, and page-number position. Omitted fields keep their current value; `platform` on its own resets the layout to that platform's baseline. Refused when the result is unprintable. Governs `produce_book` and the print estimate.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "platform": { "type": "string", "enum": [ "kdp-paperback", "kdp-hardcover", "ingramspark", "lulu", "custom" ] }, "trimPresetId": { "type": "string", "description": "A preset id from `list_trim_sizes`, e.g. \"6x9\". Wins over trimSize." }, "trimSize": { "type": "object", "description": "Custom trim: { width, height, unit: \"in\" | \"mm\" }." }, "bleed": { "type": "number", "description": "Inches of bleed (0–0.25). 0.125 is the KDP / IngramSpark spec." }, "margins": { "type": "object", "description": "Any of top, bottom, outer, inner (inches)." }, "typography": { "type": "object", "description": "Any of bodyFont, bodySize, lineHeight, headingFont, headingSize." }, "frontMatter": { "type": "object", "description": "Any of halfTitle, toc (booleans), copyrightText, dedicationText (strings)." }, "runningHeaders": { "type": "object", "description": "Any of enabled (boolean), leftPage, rightPage (\"author\"|\"title\"|\"chapter\"|\"none\")." }, "pageNumbers": { "type": "string", "enum": [ "bottom-center", "bottom-outside", "top-outside", "none" ] } }, "required": [ "bookId" ] }render_print_pdfgeneration:runKick off a print-ready PDF render for a book using its manuscript config (KDP / IngramSpark / Lulu / custom). Heavy (headless Chromium + Paged.js) — runs in a Vercel Workflow and returns a jobId; poll with `get_production_job_status`. Re-using an in-flight render for the same book returns the existing jobId (dedup).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }
Narration & audiobook
List voices, preview a sample, narrate a chapter or the whole book, and build the M4B audiobook.
narrate_chaptergeneration:runSynthesize ElevenLabs narration for a chapter and upload the MP3 to Vercel Blob. Returns the audio URL. Requires ELEVENLABS_API_KEY + BLOB_READ_WRITE_TOKEN on the server. PAID — charges narration credits (1 per ~1k characters); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }list_voicesbooks:readList the available ElevenLabs narration voices (id, name, accent, gender, age, preview URL). Use the voice id when configuring narration. Requires ELEVENLABS_API_KEY on the server.
Input schema
{ "type": "object", "properties": {} }narrate_bookgeneration:runSynthesize narration for the written, un-narrated chapters of a book, one chapter at a time, within this request's time limit (~4 minutes). PAID — each chapter is charged just before it is narrated (1 credit per ~1k characters not already narrated); if it fails or pauses, the part that wasn't narrated is refunded (saved segments stay paid and are never charged again). Long books need several calls: the result lists `remaining` chapters — call again to continue (finished chapters are skipped; paused ones resume from saved progress).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "overwriteExisting": { "type": "boolean", "description": "Re-narrate chapters that already have audio (default false)." } }, "required": [ "bookId" ] }preview_voice_samplegeneration:runSynthesize a short (~30s) ElevenLabs sample using the opening paragraph of chapter 1 so the caller can hear the voice before committing to whole-book narration. PAID but cheap — charges narration credits for the sample (1 per ~1k characters); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }export_audiobookgeneration:runConcatenate every ready-state chapter MP3 into a single M4B audiobook with embedded chapter markers, ambience, and intro/outro stings (if configured on the book). Requires every chapter to be narrated first. Uploads to Vercel Blob and returns the URL.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }extract_internal_monologue_voicegeneration:runProfile a POV character's internal-monologue voice (#15) — rumination cadence, attention pattern, somatic vocabulary, sample lines — and persist to book_character.monologueVoice. Only runs over chapters where the character is the POV. Costs LLM tokens proportional to their POV-chapter wordcount. PAID: charges 1 credit (assist); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" } }, "required": [ "bookId", "characterId" ] }
Translation
Clone the whole book into another language.
translate_bookgeneration:runCreate a new book that is a translation of an existing one into the target language (BCP-47 like "fr", "es", "pt-BR"). Clones metadata, seeds chapter shells, then translates each written chapter. EXPENSIVE — N LLM calls. PAID — charges rewrite credits per written chapter up front; refunds chapters that are not translated. Returns the new bookId.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "targetLanguage": { "type": "string", "minLength": 2 }, "sourceLanguage": { "type": "string" }, "glossary": { "type": "string", "description": "Optional Markdown list of canonical translations for proper names / specialty terms." } }, "required": [ "bookId", "targetLanguage" ] }
Sensitivity & QA
Run a sensitivity scan, list flags, and dismiss them.
run_sensitivity_scangeneration:runScan one or all written chapters for sensitive content (race, gender, religion, disability, violence, …) and persist flags. PAID — charges 1 critique credit per chapter scanned; refunds chapters not scanned on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }list_sensitivity_flagsanalytics:readList sensitivity flags for a book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }dismiss_sensitivity_flagbooks:writeMark one sensitivity flag as dismissed.
Input schema
{ "type": "object", "properties": { "flagId": { "type": "string" } }, "required": [ "flagId" ] }
Collaboration
Collaborators, chapter assignments, and the activity feed — coordinate a multi-author book.
list_collaboratorsbooks:readList collaborators on a book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }invite_collaboratorbooks:writeInvite a collaborator by email. Role: 'reader' (comments only) or 'editor' (edit access).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "email": { "type": "string" }, "role": { "type": "string", "enum": [ "reader", "editor" ] } }, "required": [ "bookId", "email", "role" ] }remove_collaboratorbooks:writeRemove a collaborator from a book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "email": { "type": "string" } }, "required": [ "bookId", "email" ] }list_chapter_assignmentsbooks:readList per-chapter assignments for a book (#89): assignee, review status, and note.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }assign_chapterbooks:writeAssign a chapter to an editor collaborator (#89), identified by assigneeEmail or assigneeUserId. Re-assigning resets status to 'assigned'. The assignee must already be an editor on the book.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "assigneeEmail": { "type": "string" }, "assigneeUserId": { "type": "string" }, "status": { "type": "string", "enum": [ "assigned", "in_review", "changes_requested", "approved" ] }, "note": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }update_assignment_statusbooks:writeUpdate a chapter assignment's review status (#89). Identify the row by chapterId; pass assigneeEmail when the chapter has more than one assignee.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "assigneeEmail": { "type": "string" }, "status": { "type": "string", "enum": [ "assigned", "in_review", "changes_requested", "approved" ] }, "note": { "type": "string" } }, "required": [ "bookId", "chapterId", "status" ] }list_activitybooks:readRead the collaboration activity / audit feed for a book (#90): invites, joins, approvals, and suggestion decisions, newest first.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 60 } }, "required": [ "bookId" ] }
Publishing
Publish / unpublish and run the end-to-end agentic publish pipeline.
publish_bookpublish:writePublish a book at /read/{slug}. Every chapter must have content. Returns the public reader URL.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "visibility": { "type": "string", "enum": [ "private", "unlisted", "public" ], "description": "Defaults to the book's current visibility." } }, "required": [ "bookId" ] }unpublish_bookpublish:writeRevert a published book to status `ready`. Reader page stops resolving.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }agentic_publishpublish:writeOne-shot publishing pipeline: outline (if needed) → write every empty chapter → optionally narrate → pick a cover color → publish to a public URL. Runs as a background job and returns a jobId immediately; poll it with `get_job_status`. Re-running while a job is active returns the existing jobId. PAID — charges up front for the work the pipeline will do (research + outline when there is no outline yet, one chapter credit per empty chapter, one assist credit for the cover color, plus estimated narration when `narrate` is set); refunded if the job fails to enqueue, and the share paying for undelivered work is refunded if the job fails or is cancelled.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "narrate": { "type": "boolean", "description": "Include whole-book ElevenLabs narration in the pipeline (paid)." } }, "required": [ "bookId" ] }
Account, jobs & analytics
Usage & spend, background-job status, reader analytics, and author preferences.
get_usageaccount:readLifetime + 30-day rollups of LLM token usage across this account, grouped by call kind (outline, chapter, rewrite, …).
Input schema
{ "type": "object", "properties": {} }get_reader_analyticsanalytics:readPer-chapter reader stats for a published book (views, audio starts, completions, drop-off).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }list_jobsanalytics:readList background jobs (outline / write / narrate / pdf). status: 'all' | 'active' | 'finished'.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "status": { "type": "string", "enum": [ "all", "active", "finished" ] }, "limit": { "type": "integer", "minimum": 1, "maximum": 50 } } }get_job_statusanalytics:readLook up one background job.
Input schema
{ "type": "object", "properties": { "jobId": { "type": "string" } }, "required": [ "jobId" ] }list_author_preferencesaccount:readRead the author's saved preferences (POV, em-dash usage, voice prefs, etc.) — applied across every book.
Input schema
{ "type": "object", "properties": {} }set_author_preferencebooks:writeSave a durable author preference (applied across every book).
Input schema
{ "type": "object", "properties": { "key": { "type": "string" }, "value": { "type": "string" } }, "required": [ "key", "value" ] }pause_jobbooks:writeRequest that a long-running job pause at its next batch boundary. The in-flight batch finishes; subsequent batches are skipped and the job exits cleanly. Returns the job's prior status.
Input schema
{ "type": "object", "properties": { "jobId": { "type": "string", "description": "Job UUID." } }, "required": [ "jobId" ] }forget_author_preferencebooks:writeDelete one saved author preference by key.
Input schema
{ "type": "object", "properties": { "key": { "type": "string" } }, "required": [ "key" ] }get_reader_statsanalytics:readAggregate reader-side telemetry for a published book — total views plus per-chapter views, audio starts, audio completions, and completion rate. Returns zeros until the reader UI starts emitting events.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }
Everything else
Tools that don't fall into a named domain above — still fully callable, still scope-gated.
get_chapterbooks:readFetch a single chapter (full prose content included).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }list_book_documentsbooks:readList writer's-bible documents (characters, plot_outline, theme_outline, style_guide, style_references, worldbuilding, research_notes, glossary, synopsis, lore, setting_bible, era_research).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }read_book_documentbooks:readRead the full content of one writer's-bible document.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kind": { "type": "string", "enum": [ "characters", "plot_outline", "theme_outline", "style_guide", "style_references", "worldbuilding", "research_notes", "glossary", "synopsis", "lore", "setting_bible", "era_research" ] } }, "required": [ "bookId", "kind" ] }write_book_documentbooks:writeCreate or overwrite one writer's-bible document. The current revision is snapshotted first so the change is recoverable.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kind": { "type": "string", "enum": [ "characters", "plot_outline", "theme_outline", "style_guide", "style_references", "worldbuilding", "research_notes", "glossary", "synopsis", "lore", "setting_bible", "era_research" ] }, "title": { "type": "string" }, "content": { "type": "string" } }, "required": [ "bookId", "kind", "content" ] }draft_book_documentgeneration:runAuto-draft one writer's-bible document from the premise + chapters. If a document already exists for that kind, pass confirm:true to overwrite it. PAID — charges 1 assist credit; refunds on failure (including the confirm/premise refusals).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kind": { "type": "string", "enum": [ "characters", "plot_outline", "theme_outline", "style_guide", "style_references", "worldbuilding", "research_notes", "glossary", "synopsis", "lore", "setting_bible", "era_research" ] }, "confirm": { "type": "boolean" }, "hint": { "type": [ "string", "null" ] } }, "required": [ "bookId", "kind" ] }list_book_document_revisionsbooks:readList saved snapshots of one writer's-bible document (newest first).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "kind": { "type": "string", "enum": [ "characters", "plot_outline", "theme_outline", "style_guide", "style_references", "worldbuilding", "research_notes", "glossary", "synopsis", "lore", "setting_bible", "era_research" ] } }, "required": [ "bookId", "kind" ] }restore_book_document_revisionbooks:writeRoll a writer's-bible document back to a saved snapshot. The current content is snapshotted first so the restore is itself undoable.
Input schema
{ "type": "object", "properties": { "revisionId": { "type": "string" } }, "required": [ "revisionId" ] }get_credit_balanceaccount:readRead the account's current credit balance (number of generation credits remaining). One illustration is one credit; chapter writes and narration draw multiple credits depending on size.
Input schema
{ "type": "object", "properties": {} }detect_confusiongeneration:runFlag any paragraph a first-time reader would need to re-read — unclear pronouns, untagged characters, settings they cannot picture, jargon, time jumps, beats arriving without setup. Returns a structured per-paragraph list. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." } }, "required": [ "bookId", "chapterId" ] }refresh_comp_titlesgeneration:runRank the closest comparable published books for the manuscript so far, replacing the prior list. Anchors on training memory of published titles (no live web fetch). If statedComps is supplied, the note calls out drift between intended and actual positioning. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "statedComps": { "type": "string", "description": "Author-named comps to compare drift against — comma-separated." } }, "required": [ "bookId" ] }list_book_comp_titlesbooks:readList the saved comp titles for a book, ordered by rank.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }list_writing_sessionsbooks:readList the user's recent writing sessions, newest first.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "limit": { "type": "number", "description": "Max sessions (1–50). Default 10." } } }session_changelogbooks:readBuild a structured changelog from a writing session — counts by event kind, accumulated notes, words added, and the auto-summary.
Input schema
{ "type": "object", "properties": { "sessionId": { "type": "string", "description": "Writing session UUID." } }, "required": [ "sessionId" ] }stuck_modegeneration:runThe author said they're stuck. Diagnose the kind of stuck, ask 3 targeted questions, and propose 3 distinct paths forward each with a concrete first step. Pass the author's verbatim message. If bookId is supplied, the last-chapter tail is attached for grounding. PAID — charges 1 assist credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "userMessage": { "type": "string", "description": "The author's verbatim message." }, "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "userMessage" ] }daily_rereadgeneration:runPick the 1–3 paragraphs from the author's recent writing most worth rereading before today's session. Uses chapters updated in the last lookbackHours (default 26). PAID — charges 1 assist credit; refunded when there is no recent writing or on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "lookbackHours": { "type": "number", "description": "Window in hours (1–168). Default 26." } }, "required": [ "bookId" ] }score_chapter_cardgeneration:runScore a chapter on five axes — voice, prose, continuity, pacing, hook — with an overall score and short notes per axis. Persists the result so regression checks can compare across rewrites. PAID — charges 1 critique credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "chapterId": { "type": "string", "description": "Chapter UUID." } }, "required": [ "bookId", "chapterId" ] }check_chapter_regressionbooks:readCompare the newest scorecard for a chapter against the previous one. Returns per-axis deltas and warns when any axis dropped by more than threshold (default 5).
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string", "description": "Chapter UUID." }, "threshold": { "type": "number", "description": "Drop threshold (1–50). Default 5." } }, "required": [ "chapterId" ] }chekhov_reportbooks:readChekhov's-gun report (#40): every introduced object that the prose never escalates past 'mentioned'. Reads chekhovStatus on book_object_state (populated by refreshObjectTracker). Zero LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "maxLatencyChapters": { "type": "integer", "minimum": 0, "default": 3 } }, "required": [ "bookId" ] }in_scene_nowbooks:readReturn the objects 'in scene right now' for a given chapter (#40), grouped by chekhovStatus. Zero LLM cost.
Input schema
{ "type": "object", "properties": { "chapterId": { "type": "string" } }, "required": [ "chapterId" ] }check_off_page_durationbooks:readReturn characters who've been off-page for too long (#16). Compares each character's lastSeenChapterOrder against the most recently written chapter; flags absences ≥ maxAbsenceChapters (default 4). Also surfaces never-seen characters and stale trackers. Pure heuristic — no LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "maxAbsenceChapters": { "type": "number", "description": "Default 4 (1-50)." } }, "required": [ "bookId" ] }check_antagonist_escalationgeneration:runAnalyse an antagonist character's tactics, motivations, and on-page intensity across the manuscript (#17). Persists the per-chapter escalation ladder to book_character.escalationLadder and returns coherence flags (drop, whiplash, motiveShift, plateau). Costs LLM tokens proportional to manuscript size. PAID: charges 1 credit (critique); refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" } }, "required": [ "bookId", "characterId" ] }lint_name_collisionsbooks:readDetect roster name pairs readers may confuse (#19) — Jon/Jonah, Mark/Marcus, etc. — by shared prefix and Levenshtein edit distance across canonical names + aliases. Pure heuristic — no LLM cost.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" } }, "required": [ "bookId" ] }check_age_appropriate_behaviorgeneration:runFlag lines where a character thinks or speaks well outside their declared age (#20). Skips characters with no age set. Pass characterId / chapterId to scope; full-roster runs are capped at 12 per call. Costs LLM tokens proportional to prose scanned × characters checked. PAID: charges 1 credit (critique) per character; refunds failed characters / on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "characterId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId" ] }analyze_setups_and_payoffsgeneration:runExtract the complete setup → payoff graph across the outline (and drafted prose where available). Persists pairs into bookForeshadowing, REPLACING prior agent-generated rows (author rows untouched). Returns orphan setups and orphan payoffs. Pass persist: false for a dry-run. Needs ≥3 chapters. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "persist": { "type": "boolean", "description": "Default true — write extracted pairs to bookForeshadowing." } }, "required": [ "bookId" ] }map_subplotsgeneration:runIdentify the book's A (main plot), B (secondary thread), and optional C threads, then map each chapter to which threads it carries. Returns threads, a per-chapter carry matrix, gap spans (thread out ≥3 chapters), and edit recommendations. Needs ≥4 chapters. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }analyze_tension_curvegeneration:runScore every chapter's tension 0–100, detect mid/late sags (≥3 consecutive low-tension chapters in a climbing section), and propose reorder/insert/compress moves. Optionally persists scores into chapters.tensionTarget; by default preserves author-set targets unless overwriteAuthorTargets: true. Needs ≥4 chapters. PAID — charges critique credits; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." }, "persist": { "type": "boolean", "description": "Write analyzed scores into chapters.tensionTarget. Defaults false." }, "overwriteAuthorTargets": { "type": "boolean", "description": "When persisting, also overwrite author-set targets. Defaults false." } }, "required": [ "bookId" ] }get_chapter_beat_mapbooks:readFor the book's chosen beat-sheet (Save the Cat / Hero's Journey / Three-Act / etc.), return the per-chapter mapping of order → structural beat (label + intent + nominal position 0..1). Pick a framework first with set_plan({ beatSheetTemplate }).
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string", "description": "Book UUID." } }, "required": [ "bookId" ] }write_all_chaptersgeneration:runWrite every remaining (empty) chapter of a book in one call. Writes chapter 1 first to seed the style bible, then fans out chapters 2..N in parallel. Pass `parallel: false` to write strictly in order when each chapter must read the previous chapter's prose. `rewriteAll: true` overwrites existing prose. Returns per-chapter words plus a failures list. Long-running — for big books prefer `enqueue_write_all_chapters`. PAID — charges one chapter credit per chapter to write; refunds every chapter not written.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "rewriteAll": { "type": "boolean", "description": "Rewrite ALL chapters (overwriting prose). Defaults false — fills empties only." }, "selfCritique": { "type": "boolean", "description": "Run the cheap consistency pass on every chapter (slower, catches drift)." }, "parallel": { "type": "boolean", "description": "Fan out chapters 2..N in parallel after chapter 1 (default true)." } }, "required": [ "bookId" ] }enqueue_write_all_chaptersgeneration:runStart write_all_chapters as a background job and return a jobId immediately, so the caller doesn't block on minutes of generation. Poll status with `get_job_status`. Refuses if another writeAllChapters job for this book is already queued or running. (In serverless deployments without a durable worker the background loop may be killed when the function exits.) PAID — charges one chapter credit per chapter to write at enqueue; the job refunds every chapter it doesn't write.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "rewriteAll": { "type": "boolean" }, "selfCritique": { "type": "boolean" } }, "required": [ "bookId" ] }preview_chaptergeneration:runGenerate one chapter's prose WITHOUT saving it. Returns the draft text so the caller can approve it before persisting with `update_chapter` / `write_chapter`. Identify the chapter by chapterId OR order. PAID — charges one chapter credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" }, "order": { "type": "integer", "minimum": 1 } }, "required": [ "bookId" ] }research_chaptergeneration:runRun focused web research (Perplexity) for ONE chapter — its title plus summary become the query. For non-fiction where each chapter needs current, sourced facts. Persists the brief inline at the END of the chapter's summary so the writer picks it up. PAID — charges one research credit; refunds on failure.
Input schema
{ "type": "object", "properties": { "bookId": { "type": "string" }, "chapterId": { "type": "string" } }, "required": [ "bookId", "chapterId" ] }research_topicgeneration:runRun web-grounded research (Perplexity) on a premise and return a sourced brief. If `bookId` is provided, the brief is saved onto that book for writing (and a cached existing brief is returned without a new call). PAID — charges one research credit for a new call (cached briefs are free); refunds on failure.
Input schema
{ "type": "object", "properties": { "premise": { "type": "string" }, "genreHint": { "type": "string" }, "bookId": { "type": "string", "description": "If set, the brief is saved onto this book." } }, "required": [ "premise" ] }