Creader helps you see your own thinking: it tracks what your writing commits to and shows where it contradicts itself. This server lets an AI assistant run Guardian, Creader's checker, on a manuscript and return the issues. Today the checks are built for fiction: characters, places, timeline, and lore. Checking is the default. Drafting tools are listed last and run only when the user asks for them.
- The user wants a draft checked against what it has already established.
- The user asks to check a chapter or manuscript for contradictions, plot holes, timeline errors, or character inconsistency.
- The user asks what their world already says about a character, place, or event.
- The user did not ask for prose. Do not call drafting tools on your own.
- guardian_check: check one chapter across five layers (consistency, style, analysis, chapter suspense, plot structure).
- vector_check: check characters, timeline, and locations across books.
- list_guardian_issues / resolve_guardian_issue: the same issue list the author sees in the editor.
- extract_entity_candidates / triage_entity_candidate / triage_entity_fact: pull world facts out of the text; the author decides what to keep.
guardian_check returns GuardianIssue items. Each has a textPosition; proofreading issues also carry a suggestedFix. Every run is saved to the book, where the author sees it in the Guardian panel; there is no run that leaves no trace. costBudget defaults to local: rule checks only, no model calls, no tokens. "local" is the cost class name; the check runs on Creader's server. Every budget, local included, needs an API key with the ai and write scopes. Layer 3 and proofreading need a model budget and use tokens.
┌─────────────────┐ MCP (stdio) ┌──────────────────┐ HTTPS ┌─────────────┐
│ Claude / GPT │ ◄────────────────► │ creader-mcp │ ◄──────────► │ Creader API │
│ or any MCP │ 79 tools │ (this server) │ REST+JSON │ creader.io │
│ client │ │ │ │ │
└─────────────────┘ │ - TTL cache │ │ - Books │
│ - Error recovery│ │ - Chapters │
│ - Tool hints │ │ - Knowledge │
│ - Batched reads │ │ - Relations │
└──────────────────┘ └─────────────┘
npx -y @creader/mcp-serverRequires a CREADER_API_KEY environment variable. Create one at creader.io under Settings > API Keys — the full tool set needs the read, write and ai scopes.
Published on npm and in the MCP Registry as io.creader/mcp-server.
Add to your MCP config:
{
"mcpServers": {
"creader": {
"command": "npx",
"args": ["-y", "@creader/mcp-server"],
"env": {
"CREADER_API_KEY": "cr_live_your_key_here"
}
}
}
}claude mcp add creader --env CREADER_API_KEY=cr_live_your_key_here -- npx -y @creader/mcp-server| Variable | Required | Default | Description |
|---|---|---|---|
CREADER_API_KEY |
Yes | — | Your Creader API key (cr_live_...) |
CREADER_API_URL |
No | https://creader.io |
Creader API base URL |
| Tool | Description |
|---|---|
list_books |
List all books |
get_book |
Get book details |
create_book |
Create a new book (novel, autobiography, worldbook, encyclopedia) |
get_book_context |
Get full book context in one call — metadata, chapters, characters, locations, events |
| Tool | Description |
|---|---|
list_chapters |
List chapters in a book (titles + word counts, no content) |
get_chapter |
Read a chapter's full content, plus the baseContentHash to pass back when writing |
create_chapter |
Create a new chapter |
update_chapter |
Write or update a chapter. Prose writes carry a baseContentHash and are rejected as a conflict — never silently overwritten — if the editor changed the chapter meanwhile |
delete_chapter |
Permanently delete a chapter (hard delete; its scenes go with it, later chapters are renumbered). Needs the delete API-key scope; book owner only |
search_book |
Search the book's prose and get back matching chapters with snippets, character offsets and chapter ids. text (exact substring, CJK-safe, exhaustive) or semantic (meaning-based, indexed chapters only). Not the same as search_knowledge, which searches entity records |
reorder_chapters |
Reorder a book's chapters. Takes the complete chapter-ID list in the new order; writes only the positions that changed. The server has no atomic reorder, so an interrupted run reports exactly which chapters moved and is safe to re-run |
Creader organises a book as volume → act → chapter → scene. Full CRUD on
all three levels around chapters, so an agent can build the spine it writes
into (acts carry their volumeId; scenes carry their chapterId/actId).
Two naming traps: acts are named (name) while volumes and scenes are
titled (title); and orderIndex is scoped to the parent, so omit it and
the server appends.
| Tool | Description |
|---|---|
list_volumes |
List a book's volumes with chapter counts |
list_acts |
List a book's acts and which volume each belongs to |
list_scenes |
List a book's scenes with their parent chapter/act, status, and synopsis |
create_volume |
Create a volume — the top level of the spine, holding acts and chapters. Omit orderIndex to append at the end |
update_volume |
Update a volume's fields. Only what you pass changes |
delete_volume |
Delete a volume. Also deletes the chapters inside it and inside its acts, prose included, and those chapters' scenes — permanently, in one transaction. Counts what would die and refuses until you pass that exact number as confirmChapterCount; an empty volume needs no confirmation. Move the chapters elsewhere with update_chapter first to keep the prose |
create_act |
Create an act. Acts are named, not titled. Pass volumeId to put it inside a volume; omit orderIndex to append |
update_act |
Update an act's fields. Pass volumeId: null to detach it from its volume |
delete_act |
Delete an act. Also deletes the chapters inside it, prose included, and those chapters' scenes — permanently, in one transaction. Counts what would die and refuses until you pass that exact number as confirmChapterCount; an empty act needs no confirmation. Move the chapters to another act with update_chapter first to keep the prose |
create_scene |
Create a scene — a unit of plan inside a chapter and/or act. Link it with chapterId and actId; omit orderIndex to append |
update_scene |
Update a scene's fields. Pass null to clear a link (chapterId, actId, locationId) |
delete_scene |
Delete a scene. Permanent, but it takes nothing with it — a scene is a plan record and the chapter's prose is untouched |
Extraction proposes; the writer decides. Nothing reaches the world unreviewed.
| Tool | Description |
|---|---|
extract_entity_candidates |
Read one chapter and fill two queues in one paid call: new entities, and facts about entities that already exist. Spends token quota (both legs); needs the ai scope. Reports when only part of a long chapter was examined |
list_entity_candidates |
New entities awaiting the writer's decision. Free |
triage_entity_candidate |
ACCEPTED confirms the draft record into a real entity; DISMISSED deletes it. Either way the name is never proposed again |
list_entity_facts |
Proposed facts about existing entities, ordered by the chapter that established each. Free; status defaults to PENDING |
triage_entity_fact |
ACCEPTED appends to the fact log — it does not rewrite the author's card. DISMISSED keeps the row so the statement is not proposed again |
This is the honest successor to extract_facts (removed in v1.4.0 when the
product deleted its route), not that tool renamed. The old one proposed a delta
and handed it back for the caller to apply; this is a queue the writer owns.
Both halves ship together on purpose. One extract_entity_candidates call runs
and bills two LLM legs — discovery writes EntityCandidate rows, the maintain
leg writes EntityFact rows. Shipping only the candidate half would bill the
writer for output no client could read.
Two different things share the word. The fingerprint is measured from the author's prose; the references are passages they chose.
| Tool | Description |
|---|---|
get_style |
The book's measured style fingerprint — sentence/paragraph length, vocabulary diversity, structure mix, tone, POV, tense, commonest words. null means not yet computed, not styleless |
list_style_references |
The author's chosen exemplar passages, plus whether style learning is on |
add_style_references |
Add passages to the voice corpus (≤50 per call, ≤2000 chars each, 500 per book). Reports when the server trimmed the batch to fit the cap. Creator plan |
delete_style_reference |
Remove one exemplar. No prose is touched |
set_style_learning |
Whether Creader feeds the references into its own AI calls. Creator plan |
There is deliberately no set_style. PUT /style exists and takes an API
key, so the tool would have been two lines — but the fingerprint is a
measurement of prose that exists, computed by the style analyzer. A model
authoring one fabricates the measurement, and every later AI call on that book
is steered by it: chat, inline, the L2 detectors. It fails silently, in the
wrong voice.
The Twitter-archive import is not wrapped either — it is a multipart file
upload, and the same rows can be created through add_style_references with
source archive_import.
The book as designed — volumes → acts → chapters → scenes, with beats on chapters and subplot threads on volumes.
| Tool | Description |
|---|---|
get_plan_spine |
The whole plan tree in one call, without chapter prose — the route returns full Chapter rows, and forwarding them would spend a book of context per call. Chapters belonging to no act come back under unassignedChapters rather than disappearing |
list_plot_nodes |
Every beat in the book, flat and ordered by chapter then position |
create_plot_node |
Add a beat to a chapter. Omit order to append; threadIds attaches subplots; setupId records the foreshadowing setup this beat plants (a payoff id is rejected) |
update_plot_node |
Change a beat's wording, position, chapter or threads. threadIds replaces the set — [] detaches from all |
delete_plot_node |
Delete a beat. The chapter and its prose are untouched |
reorder_plot_nodes |
Reposition many beats in one transaction — unlike reorder_chapters, one bad id rejects the batch without moving anything |
create_plan_thread |
Create a subplot thread on a volume (the axis beats attach to; color drives the grid column) |
apply_structure_template |
Lay down three-act / heros-journey / save-the-cat on an empty plan, atomically. A plan with content is never overwritten — the template is recorded as a declaration and the reply says so |
POST /plan/generate-beats is deliberately not wrapped: it asks a model to
invent beats, and the MCP client is already a model. Write the beats, then call
create_plot_node.
Deprecation notice (v1.3.0): the 12 per-type CRUD tools below are deprecated. v2.0.0 consolidates them into
create_entity/update_entity/delete_entitywith atypediscriminator (see docs/UPGRADE_PLAN.md). They remain fully functional throughout 1.x — keep using them until v2.0.0 ships, then migrate with the table in that release's notes.
| Tool | Description |
|---|---|
search_knowledge |
Substring search across characters, locations, events, and notes (case-insensitive, CJK-safe; queries must be 2+ characters). For the prose itself, use search_book |
list_knowledge |
List characters, locations, or events in a book |
create_character (deprecated) |
Create a character (protagonist, antagonist, supporting, minor) |
create_location (deprecated) |
Create a location |
create_event (deprecated) |
Create a timeline event |
create_note (deprecated) |
Create a note (worldbuilding, research, note, general) or a world constraint (rule / prohibition) — constraints are force-injected into every AI prompt for the book and capped per plan |
update_character (deprecated) |
Update a character's fields |
update_location (deprecated) |
Update a location's fields |
update_event (deprecated) |
Update a timeline event's fields |
update_note (deprecated) |
Update a note's fields |
delete_character (deprecated) |
Delete a character |
delete_location (deprecated) |
Delete a location |
delete_event (deprecated) |
Delete a timeline event |
delete_note (deprecated) |
Delete a note |
| Tool | Description |
|---|---|
list_relations |
List semantic relations (entity-to-entity relationships) in a book |
create_relation |
Create a relation between two entities (e.g. allies_with, located_in) |
update_relation |
Update a relation's type, description, or strength |
delete_relation |
Delete a relation |
| Tool | Description |
|---|---|
generate_outline |
Generate a story outline with structured chapter suggestions from a premise |
guardian_check |
Run the 5-layer narrative Guardian on one chapter. Choose layers and a costBudget; returns GuardianIssues with char-offset textPosition (and suggestedFix on layer-2 proofreading), plus a per-layer roll-up of detector errors and truncation. Every run is saved to the book by the server — there is no run that leaves no trace. Needs the ai and write scopes on every budget |
vector_check |
Cross-book semantic conflict detection via embeddings. Detects near-duplicate content and timeline inconsistencies between events. Operates on already-indexed content |
list_guardian_issues |
List the issues currently OPEN on a book — the same notes the author sees in the Guardian panel, whoever created them. Optionally narrowed to one chapter |
resolve_guardian_issue |
Close an issue (RESOLVED / DISMISSED) or reopen it, addressed by fingerprint. Dismissal also feeds detector confidence |
orchestrate |
Turn a writing intent (plus optional outline and book context) into a structured generation plan: scene breakdown, consistency constraints, style directives, word target, creative prompt. Spends token quota; needs the ai scope |
guardian_check fronts Creader's single Guardian dispatcher. It replaced
consistency_check, analyze_book and proofread, whose routes were deleted
from the product on 2026-05-01 — all three had been returning 404 to every
caller since.
extract_facts went the same way in v1.4.0: the product retired the whole
fact-delta chain on 2026-08-27, so /api/ai/extract-facts no longer exists.
Nothing replaces it under that name — entity discovery from prose is a
different contract (a review queue of proposed new entities and field
updates) and will arrive as its own tool.
Every guardian_check run is saved by the run route itself, and has been since
2026-05-27: the findings land in the author's Guardian panel and count toward
Story Health, and open notes on the chapter that the detectors which ran no
longer raise are closed in the same step.
Up to and including v1.10.0 this server did not know that, and wrote the
findings a second time through the issues collection. That write was worse
than redundant. It carries only a narrow subset of each issue, so it blanked
the detector, evidence, description, lane and sources the run had just stored;
it names no detectors, so its clean-up was chapter-wide and a free local
check resolved every deep-run note on the chapter; and it is capped at 200
issues, so a bigger run resolved its own overflow. It is gone. The tool now
makes two requests — the chapter read and the run — and saved in the result
reports the server's own verdict: persisted, the count of issues the run
saved, and a reason when there is something to explain.
What follows from the route doing the saving:
- Scopes. The route demands
aiandwriteof an API key on every budget,localincluded. A key missing either is refused before anything runs, so nothing is billed and nothing comes back. - A failed save is not a failed run. If the server cannot write the rows
after the run, the findings still come back, with
saved.persisted: false. - No traceless run. The route has no opt-out. The old
persistflag never turned saving off (it only skipped the second write) and has been removed; a caller that still sends it is not rejected, the key is ignored.
The issue routes opened to API keys on 2026-08-29 (read to list, write to
transition), so the two sides share one queue: list_guardian_issues shows
what the author flagged in the editor, and an issue you resolve disappears from
their panel.
| Layer | What it checks |
|---|---|
| 1 | Consistency — dead characters, name typos, timeline and entity contradictions |
| 2 | Style & Prose — cliche, weak verbs, dialogue tags, POV leak, proofreading |
| 3 | Analysis — character arcs, causal chains, literary quality |
| 4 | Chapter & Suspense — opening quality, suspense, thread coverage, cliffhangers |
| 5 | Plot Structure — three-act shape, inciting incident, midpoint, foreshadowing |
costBudget is an inclusive ceiling on how expensive a detector may be:
local(default): rule checks only, no model calls, no tokens. "local" is the cost class name; the check runs on Creader's server and needs the sameaiandwritescopes as any other run. Reaches only the rule-based detectors, so layer 3 returns nothing and layers 1/2/4/5 return only their local subset (cliche and repetition yes, proofreading and POV leak no).api-light/vector/api-heavy: progressively deeper.api-heavyis the full pass; it uses the account's tokens.
| Tool | Description |
|---|---|
get_writing_stats |
Writing streak, daily/weekly word progress against goals, and total writing days |
get_quota |
Check remaining AI token quota |
set_visibility |
Publish or unpublish a book (PRIVATE, LINK_ONLY, PUBLIC). Every chapter — drafts included — is set to match, overwriting per-chapter visibility; volumes are clamped down on a downgrade. Needs an API key with the publish scope, which keys don't get by default |
An article is a standalone piece — an essay, a blog post, a student draft — owned by the writer rather than by a book. No chapters, characters or structure around it, so none of the book tools apply.
| Tool | Description |
|---|---|
list_articles |
List the writer's articles, newest edit first (no content). status: active (default), archived or all |
get_article |
Read an article's full content, plus the baseContentHash to pass back when writing |
create_article |
Create an article. It starts PRIVATE |
update_article |
Change the title, content or status (archived puts it away without deleting it). Content writes need a baseContentHash and are refused if the prose changed since that read; see below |
delete_article |
Permanently delete an article, with its notes, Guardian issues, comments and comment invitations. Needs the delete scope; owner only |
set_article_visibility |
Publish (PUBLIC / LINK_ONLY) or unpublish (PRIVATE), optionally choosing the slug and search-engine consent. Also switches on the writer's public profile page. Needs the publish scope |
guardian_check_article |
Run Guardian on an article. It reads the piece as an essay rather than fiction, so a requested layer with nothing to run is named in deferredLayers. Always saves its findings, so it needs the write scope; api-heavy also needs ai |
list_article_guardian_issues |
List the issues open on an article; includeAccepted adds the ones the writer has accepted but not fixed yet |
resolve_article_guardian_issue |
Close (RESOLVED / DISMISSED) or reopen an issue, addressed by its id |
list_article_notes |
List the notes kept on an article |
create_article_note |
Add a note to an article. update_note / delete_note take its id like any other note |
update_article sends your baseContentHash with the new content, and a
Creader deployment with the article guard compare-and-swaps the write the way
it does a chapter's: if the prose changed since that read, the write is refused
as a conflict and nothing is written. That closes the race.
A deployment that predates the guard ignores the hash and writes
last-write-wins, so update_article also makes the check itself: it re-reads
the article just before writing and refuses if the prose no longer matches the
version your baseContentHash describes. Against such a deployment that
narrows the window to the moment between the re-read and the write, but cannot
close it. The re-read stays until the guard is deployed everywhere.
Comments, comment invitations and AI prose proposals also exist on articles, but their routes accept a browser session only, so the MCP server has no access to them.
New to Creader? This guide explains which tool to use for each type of content, so your story data stays organized and renders correctly on creader.io.
Book
├── Volumes ← Top-level grouping (list_volumes)
│ └── Acts ← Group chapters within a volume (list_acts)
├── Chapters ← Actual prose, outlines, and story content
│ └── Scenes ← Beats within a chapter (list_scenes)
├── Knowledge Base
│ ├── Characters ← People, creatures, named entities in your world
│ ├── Locations ← Places — cities, rooms, planets, forests
│ ├── Events ← Timeline entries — plot points, turning points, backstory
│ └── Notes ← Worldbuilding rules, research, agent-to-agent messages
└── Relations ← Connections between any two entities above
Article ← A standalone essay or post, owned by the writer — not part of any book
├── Notes ← Research and sources kept beside it (create_article_note)
└── Guardian issues ← Its own review queue (list_article_guardian_issues)
| Content | Use This | NOT This | Why |
|---|---|---|---|
| Chapter text / prose | create_chapter / update_chapter |
Notes or Knowledge Base | Chapters render as readable pages on creader.io |
| Story outline | generate_outline → then create_chapter per chapter |
Knowledge Base notes | Outlines are chapter-level structure — store them as chapters so they show up in the chapter list |
| Character profiles | create_character |
Notes | Characters have structured fields (role, age, tags) and appear in the World Foundation panel on creader.io |
| Locations / settings | create_location |
Notes | Locations have type fields (city, forest, castle) and appear in World Foundation |
| Timeline / plot events | create_event |
Notes or chapters | Events have timestamps, importance levels, and consequences — they power the timeline view on creader.io |
| World rules / magic systems | create_note (type: worldbuilding) |
Characters or Events | Notes are for unstructured world lore that doesn't fit other categories |
| Research / reference material | create_note (type: research) |
Events | Notes keep research separate from story content |
| Agent-to-agent messages | create_note (type: note) |
— | When multiple agents collaborate, use notes as a message board |
| Character relationships | create_relation |
Character description field | Relations are queryable and have strength scores — don't bury relationships in description text |
| Location hierarchy | create_relation (type: contains / located_in) |
Location description | "City contains District" is a relation, not a description |
Starting a new book:
1. create_book (pick the right type: novel, worldbook, etc.)
2. Create your world foundation FIRST:
- create_character × N (protagonist, antagonist, supporting cast)
- create_location × N (key settings)
- create_event × N (major plot points on the timeline)
- create_relation × N (how characters/locations/events connect)
3. generate_outline → review → create_chapter for each outline item
4. get_book_context → write chapters with full world awareness
Continuing an existing book:
1. get_book_context → load everything into memory
2. list_relations → understand entity connections
3. Write / update chapters
4. Update knowledge base as the story evolves
Multi-agent collaboration:
Agent A (World Builder): creates characters, locations, events, relations
Agent A: create_note("Outline complete, ready for writing", type: "note")
Agent B (Writer): search_knowledge("ready for writing") → get_book_context → write chapters
Agent B: create_note("Chapter 1 draft done, needs review", type: "note")
| MCP Tool | Creader Website Location |
|---|---|
| Chapters | Chapter list — readable as story pages |
| Characters | World Foundation → Characters panel |
| Locations | World Foundation → Locations panel |
| Events | World Foundation → Timeline view |
| Notes | World Foundation → Notes section |
| Relations | World Foundation → Relations graph |
| Book visibility | Controls whether the book is publicly accessible |
Tip: Content created via MCP is the same data shown on creader.io. If something looks wrong on the website, check that you stored it in the right place using the table above.
get_book_context fires 5 parallel API requests and returns the full story world in a single tool call. This is critical for AI writing — the agent needs characters, locations, events, and chapter structure before it can write a coherent paragraph.
Relations aren't just labels — they have types (allies_with, located_in, caused), inverse types (has_ally, contains), and strength scores (1–10). This lets agents reason about narrative structure: "Who is allied with the protagonist?", "What events caused the current conflict?", "Which characters are in this location?"
The MCP server is a long-running process. Claude may call get_book_context on every turn. The cache stores GET responses for 60 seconds and clears automatically on any write, so agents always see fresh data without hammering the API.
Tool responses use concise text format (- Character Name (protagonist) id:abc123) instead of raw JSON. This reduces token consumption and lets the LLM process results faster.
- Tool annotations —
readOnlyHint,destructiveHint,openWorldHinton every tool, so clients can make informed decisions about tool execution - Server instructions — guides the LLM on optimal tool usage patterns during MCP handshake
- Error recovery — errors returned with
isErrorflag so the LLM can self-correct without crashing the conversation
Agent A builds the world, Agent B writes chapters — both connected to the same Creader book:
Agent A: create_book → create_character × 3 → create_location × 2 → create_event × 3
create_relation (character allies_with character)
create_relation (character located_in location)
Agent B: get_book_context → list_relations → get_chapter → update_chapter × N
Agent A: create_note (feedback for Agent B)
Agent B: search_knowledge ("feedback") → update_chapter (revise)
You: "Write chapter 1 of my fantasy novel"
Claude: get_book_context → get full story world
list_relations → understand character dynamics
get_chapter (ch1) → read existing content
update_chapter (ch1) → write the chapter
You: "Build out the world for my detective novel"
Claude: create_character ("Detective Hayes", protagonist)
create_character ("Mayor Chen", antagonist)
create_location ("Harborview", city)
create_relation (Hayes, located_in, Harborview)
create_relation (Hayes, investigates, Chen, inverse: investigated_by, strength: 8)
create_event ("Murder at the docks", plot, major)
git clone https://github.com/timothyshen/creader-mcp
cd creader-mcp
pnpm install
pnpm buildCREADER_API_KEY=cr_live_... CREADER_API_URL=http://localhost:3000 node dist/index.jsThe project ships with a unit suite (mocked fetch) and an integration suite (real Creader API, opt-in).
pnpm test # unit tests only — fast, no network
pnpm test:watch # unit tests in watch mode
pnpm test:coverage # unit tests + v8 coverage report (70% threshold)
pnpm test:integration # integration tests — auto-skipped without a token
pnpm test:all # everythingIntegration tests are read-only and gated on CREADER_API_TOKEN. Without the token they skip silently, so CI without the secret stays green.
export CREADER_API_TOKEN=cr_live_...
export CREADER_API_URL=https://creader.io # optional override
pnpm test:integrationCoverage reports are written to coverage/ (HTML at coverage/index.html, plus lcov.info for CI tooling).
MIT