# Unblockifier MCP server: agent guide

Unblockifier is novel-writing software. AI helps along the way. It never writes. A handful of tools read what you've written and hand something back: story elements found in a draft, a character's arc tracked chapter by chapter, a full editorial read in the voice you choose. None of them write a sentence of your prose. That's true of every one, including the chat box beside the page.
This guide is for AI agents connecting to its MCP server, which gives a writer's own assistant access to their projects: reading them, and adding to their notes if the writer allows it. It is generated from the server's own code, so it matches what the server does.

## Connecting

- Endpoint: `https://unblockifier.com/mcp` (Streamable HTTP, JSON responses, no server-sent events). The earlier address `https://unblockifier.com/mcp/writer` reaches the same server.
- Sign-in: OAuth 2.1 with PKCE (S256) and Dynamic Client Registration. A call that needs a token and has none gets a 401 whose `WWW-Authenticate` header points at the protected resource metadata (`https://unblockifier.com/.well-known/oauth-protected-resource/mcp`). `server/discover`, `initialize`, and `ping` need no token. Authorization server metadata: `https://unblockifier.com/.well-known/oauth-authorization-server`.
- Permissions the writer grants on the consent screen: `story:read` (always: the project list, chapters and scenes with word counts, and the names of story elements), `manuscript:read` (only if they allow it: the text of chapters and scenes, and the contents of notes and story elements), and `story:write` (only if they allow it: adding to and replacing notes). A call that needs a permission the token lacks gets a 403 with `error="insufficient_scope"` naming it. Ask the writer to reconnect and allow it.
- Tokens work only at this server, expire after an hour, and are renewed with the refresh token. A refresh token or code works once; using one twice ends the connection.
- Rate limit: 600 requests a minute per calling address. Over that, the server answers 429 with `Retry-After: 60`. Wait, then retry.
- Current protocol revision (2026-07-28): stateless. Put `io.modelcontextprotocol/protocolVersion` in `params._meta`, and send the headers `MCP-Protocol-Version`, `Mcp-Method`, and (for `tools/call`) `Mcp-Name`, each matching the body. A mismatch is a 400 with error code -32020. An unsupported version is a 400 with -32022, listing the versions it supports. Call `server/discover` to learn what the server offers.
- Earlier revisions (2025-11-25, 2025-06-18, 2025-03-26): a client that opens with `initialize` is served too. The server keeps no sessions.
- Also: the server card at `https://unblockifier.com/.well-known/mcp/server-card.json`, `https://unblockifier.com/llms.txt`, and the connection page at `https://unblockifier.com/mcp-info/`.

## Tools

Every tool only reads, except `append_field` and `replace_field`, which change a field and need the `story:write` permission. Every tool that writes has a matching tool that reads (`read_field`), so a change can always be checked. Nothing in this server can change a manuscript.

### `list_projects`

Your Unblockifier projects: title, genre, chapter and scene counts, and word count. Start here, then use get_project. Permission: `story:read`.

Arguments: none.

### `get_project`

One project's chapters in order, each with its scenes (titles and word counts). Use the ids it returns with read_chapter and read_scene. Permission: `story:read`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id, as returned by list_projects.

### `read_chapter`

The text of one chapter, scene by scene. Needs the permission to read the writer's writing. If the chapter is long, the answer stops at 60,000 characters and lists the scenes to read next with read_scene. Permission: `manuscript:read`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `chapter` (string, required, up to 40 characters): The chapter's id, as returned by get_project.

### `read_scene`

The text of one scene. Needs the permission to read the writer's writing. A scene over 60,000 characters comes in parts: use next_offset as the offset to read the next part. Permission: `manuscript:read`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `scene` (string, required, up to 40 characters): The scene's id, as returned by get_project.
- `offset` (integer, optional, 0 to 10000000, default 0): Where to start, in characters. Leave out to start at the beginning.

### `list_story_kinds`

List the kinds of story element a project can hold (characters, locations, factions, and so on, with chapters and scenes as kinds too), each with the fields it has. Each field gives its "format" (the longest it may be, "max_length", and whether it must stay on one line, "one_line"), so you can fit your text before you write it, and says whether it can be changed ("can_change") and how: "add_or_replace", "replace_only" for one-line fields, or "read_only". Use it to see what exists before you read or change anything. Pass "project" to also get how many of each kind that project has, and "kind" (such as "character") to get just that one, which is much shorter. Permission: `story:read`.

Arguments:
- `project` (string, optional, up to 40 characters): The project's id. Leave out to get only the kinds and their fields.
- `kind` (string, optional, up to 40 characters): Only this kind, such as "character": a much shorter answer. Leave out for every kind.

### `list_story_elements`

List what a project holds: chapters, scenes, characters, locations, and every other kind of story element, by name and kind, with the id of each. Narrow it with "kind" (see list_story_kinds) or "query" (part of a name). Chapters and scenes come first, in book order. A long list comes in pages: use next_offset as the offset to continue. Permission: `story:read`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `kind` (string, optional, up to 40 characters): Only this kind, such as "character", "location", "chapter", or "scene". Leave out for every kind.
- `query` (string, optional, up to 100 characters): Part of a name, such as "Fred". Leave out to list them all.
- `limit` (integer, optional, 1 to 200, default 50): How many to return, up to 200.
- `offset` (integer, optional, 0 to 100000, default 0): Where to start in the list. Leave out to start at the beginning.

### `get_story_element`

Everything on one chapter, scene, or story element, as the writer has it: its fields, summary, tags, note, and (for characters, locations, and the like) who it is connected to and which scenes it appears in. Use it for "tell me about Fred". Send the element's "name" or its "item" id. If several elements fit a name, you get the list to choose from. Never includes manuscript text: read_chapter and read_scene do that. Needs the permission to read the writer's writing. Permission: `manuscript:read`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `name` (string, optional, up to 255 characters): The element's name, such as "Fred". Capitals do not matter. Send this or "item".
- `item` (string, optional, up to 40 characters): The id of a chapter or scene (from get_project) or a story element (from list_story_elements). Send this or "name".

### `read_field`

Read one field exactly as it is written: a character's role_in_story, a location's history, a summary, a note. "field" is a name from list_story_kinds (every kind also has name, summary, tags, in_world_date, and note; a project has only note). Without "item" it reads the project's own note. With "item" it reads that chapter, scene, or story element (ids from get_project or list_story_elements). Use it to check what you changed. Needs the permission to read the writer's writing. A field over 60,000 characters comes in parts: use next_offset as the offset to continue. Permission: `manuscript:read`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `item` (string, optional, up to 40 characters): A chapter or scene id from get_project, or a story element id from list_story_elements. Leave out for the project's own note.
- `field` (string, required, up to 60 characters): Which field, such as "role_in_story", "backstory", "summary", or "note".
- `offset` (integer, optional, 0 to 10000000, default 0): Where to start, in characters. Leave out to start at the beginning.

### `append_field`

Add to a field, as the writer asked. Your text goes at the end of the field, after what is already there, and ends with "(added via connector)". Nothing already there is changed. Only long fields can be added to: a one-line field (list_story_kinds says which) must be replaced with replace_field instead. list_story_kinds also says which fields can be changed at all (some can only be read for now) and the maximum length of each. Without "item" it adds to the project's own note. Use this for any request to add, jot down, or remember something, such as "add a note that Fred has a big nose" (field "note"). To check what you added, use read_field. Permission: `story:write`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `item` (string, optional, up to 40 characters): A chapter or scene id from get_project, or a story element id from list_story_elements. Leave out for the project's own note.
- `field` (string, required, up to 60 characters): Which field, such as "backstory" or "note".
- `text` (string, required, up to 20000 characters): What to add, in the writer's words where you can. Do not add the "(added via connector)" ending: it is added for you.

### `replace_field`

Replace a whole field with new text, and the old text is gone from the field. Use this ONLY when the writer has explicitly asked you to replace, change, or set it, for example "change Fred's role in the story to mentor". To add something, use append_field. To see the field first, use read_field. Keep to the format list_story_kinds gives for the field: a one-line field must stay on one line, and every field has a maximum length. The old value is kept in the change log, and for a chapter, scene, or story element the writer can put it back from its History. list_story_kinds says which fields can be changed. Without "item" it replaces the project's own note. Permission: `story:write`.

Arguments:
- `project` (string, required, up to 40 characters): The project's id.
- `item` (string, optional, up to 40 characters): A chapter or scene id from get_project, or a story element id from list_story_elements. Leave out for the project's own note.
- `field` (string, required, up to 60 characters): Which field, such as "role_in_story" or "note".
- `text` (string, required, up to 60000 characters): The new value, complete. It replaces everything that is there now.

## Working rules

- Everything you read is private to this writer. Use it to help them in this conversation, and do not repeat it elsewhere.
- Start with `list_projects`, then `get_project` for the chapter and scene ids.
- Scenes the writer set aside from the manuscript have no text, and deleted writing is never returned.
- A chapter or scene too long for one answer comes back in parts: follow `continue_with_read_scene` and `next_offset`.
- A tool error (`isError`) says what to fix. Read it, correct the arguments, and call again.
- To add to a field, use `append_field`. Your text is added at the end of the field, and ends with "(added via connector)" (added for you: do not add it yourself). Nothing already there changes. A note is the field `note`: "add a note to Fred" is `append_field` with field `note`.
- To tell the writer about something in their story, use `get_story_element` with its name or id: it returns the fields, summary, tags, note, connections, and appearances. `list_story_kinds` shows what kinds exist and which fields each has, and `list_story_elements` lists them (chapters and scenes included).
- A story element's fields are the writer's own writing. Read before you answer; do not guess what a character looks like or what a location is called.
- Use `read_field` to read one field exactly as written: to check what you added, or to see a field before replacing it.
- Use `replace_field` only when the writer has explicitly asked you to replace, change, or set a field, such as "change Fred's role in the story to mentor". It overwrites the whole field. For a chapter, scene, or story element the writer can put the old value back from its History.
- `list_story_kinds` shows every field and whether it can be changed (`can_change`) and how (`add_or_replace`, `replace_only` for one-line fields, or `read_only`). Every field has a `format`: `max_length` (the most it may hold: a one-line field is at most 200 characters unless it has a tighter limit, such as `age` at 40) and `one_line`. Fit your text to it before you write. A one-line field cannot be added to and must stay on one line. Fields marked `read_only` cannot be changed yet: say so, rather than trying. Chapters and scenes come from `get_project`, story elements from `list_story_elements`. Leave `item` out for the project's own note.
- Change something only when the writer asks. Do not write to fields of your own accord. A writer's assistants may make 60 changes an hour in all.
