---
title: "Chapter Chat"
method: POST
path: "/api/mcp/chapter_chat"
tags: ["mcp"]
---

# Chapter Chat

`POST /api/mcp/chapter_chat`

## Request

- Base URL: `https://writer.swapp1990.org` (the document declares no server; this is the origin it was published from)
- URL: `https://writer.swapp1990.org/api/mcp/chapter_chat`
- Auth: none declared

Conversational reply for back-and-forth in the revise panel.

Use this on every user-typed message. Returns a short free-text
editor response — questions answered, ideas brainstormed, critique
given, suggested changes described — WITHOUT generating a
structured plan. The UI shows a "Ready for plan?" button after
each reply; clicking that calls plan_revision with the full
conversation to synthesize the plan.

Returns: {chapter: int, editorial_summary: str}

## Request body

- ChapterChatInput
  - `job_id` string, required: The story job ID.
  - `chapter` integer, required
  - `message` string, required: User message — question, brainstorm, or revision instruction.
  - `messages` PlanMessage[]: Conversation history.
    - `role` string, required
    - `content` string
    - `plan` object, nullable
    - `cover` object, nullable
    - `writer_thinking` string, nullable
    - `writer_thinking_data` object, nullable
    - `metadata` object, nullable
    - `type` string, nullable
    - `applied_at` string, nullable
    - `applied_revision` integer, nullable
    - `applied_status` string, nullable
  - `model` string, nullable: Model override.
  - `revision` integer, nullable: Which revision to use as context. None = latest.
  - `use_story_tool` boolean: If true, run the chat as an agentic tool-use loop so the model can call the story-query tool (semantic search / read by address) over the whole story mid-conversation. Live models only; default false.
  - `target_words` integer, nullable: Target word count for the revised chapter. The planner uses this to size beats appropriately — without it, the planner defaults to the base chapter's current length, which produces beats that are too small when the user wants a meaningfully longer rewrite.
  - `authoring_mode` 'server' | 'client', nullable: Set to 'client' to have plan_revision return a no-LLM planning brief or commit client_plan.
  - `server_llm` boolean, nullable: Set false as an alias for authoring_mode='client'. Do not send model in this mode.
  - `client_plan` ClientRevisionPlanInput
    - `short_plan` string, required: Concise user-facing plan summary.
    - `long_plan` string, required: Detailed writer-facing revision plan.
    - `revision_mode` 'surgical' | 'scene_rewrite' | 'full_rewrite', nullable
    - `beats` ClientRevisionBeatInput[], required: Ordered beats for the revised chapter. The summaries should read as the chapter's main event outline; details add local beat-specific material only.
      - `num` integer, nullable: 1-based beat number in revised chapter order.
      - `index` integer, nullable: Compatibility alias for num.
      - `summary` string, required: Main event of this beat, written as part of the chapter outline. If all beat summaries are read in order, they should cover the chapter's main things that happen. Use a specific event sentence, not a vague location/title such as 'Character in bedroom'. Each beat should have a unique story function or state change, not merely repeat mood, desire, risk, or setting.
      - `details` string, required: Beat-level elaboration: local context, concrete inclusions, emphasis, action/dialogue texture, or constraints specific to this beat. This is not full prose and not meta advice about style; it states what the beat should contain beyond the summary. For explicit adult beats, include the specific physical/logistical/camera/clothing continuity the writer must render.
      - `type` 'scene_break' | 'action' | 'revelation' | 'decision' | 'dialogue' | 'reflection' | 'explicit', required: Dominant movement category for this beat's main event.
      - `title` string, nullable: Compatibility alias for summary.
      - `description` string, nullable: Compatibility alias for details.
      - `category` 'scene_break' | 'action' | 'revelation' | 'decision' | 'dialogue' | 'reflection' | 'explicit', nullable: Compatibility alias for type.
      - `change` string, nullable: Compatibility field for the requested change in this beat.
      - `story_function` string, nullable: Optional note on why this beat matters in the chapter sequence.
      - `budget_action` 'bridge' | 'compress' | 'expand' | 'preserve', nullable: Optional qualitative budget action. Do not include per-beat target_words.
      - `budget_note` string, nullable: Optional qualitative budget guidance. Do not include word-count budgets.
      - `characters` string[]: Optional character names present in this beat.
  - `base_text_hash` string, nullable: Hash returned by the no-LLM plan_revision brief; required when submitting client_plan.
  - `scope` 'chapter' | 'paragraph' | 'range': Client revision-planning scope.
  - `paragraph_index` integer, nullable: 0-based paragraph index for client paragraph-scope revision planning.
  - `paragraph_range` integer[], nullable: 0-based inclusive [start, end] paragraph range for client range-scope revision planning.
  - `include_full_text` boolean: Client mode only: include full current chapter text in the planning brief instead of the compact context excerpt.
  - `revision_mode` 'surgical' | 'scene_rewrite' | 'full_rewrite', nullable: Client-declared revision mode for client_plan provenance.
  - `plan_purpose` 'revision' | 'as_written_rebaseline', nullable: Purpose of a submitted client revision plan.
  - `supersedes_plan_id` string, nullable: Prior immutable plan artifact superseded by this rebaseline.
  - `client_name` string: Client identity for no-LLM provenance.
  - `client_model` string, nullable: Client-side model name for no-LLM provenance. Never used for server API calls.
  - `artifact_version` string: Version label for submitted client_plan artifacts.
  - `auto_save` boolean: If true (default), the server appends user+assistant turns to the chapter's chat history so get_chat returns them next call. Chat clients that manage history themselves can pass false.
  - `request_id` string, nullable: Client-supplied idempotency key. If the same id is sent again within the cache TTL, the server returns the original response without re-running the LLM. Lets mobile clients retry a backgrounded request without losing the reply or spending the model call again.

## Response `200`

Successful Response

- GenericToolResponse: Fallback for tools whose payload is still being tightened.
  - `story_url` string, nullable
  - `article_url` string, nullable
  - `job_id` string, nullable
  - `status` string, nullable
  - `is_terminal` boolean, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/swapp1990/apis/writeforyou-mcp-api.md) · [All operations](https://skmtc.dev/swapp1990/apis/writeforyou-mcp-api/llms.txt) · [OpenAPI document](https://skmtc.dev/swapp1990/apis/writeforyou-mcp-api/revisions/ce5e2a89ab4d?raw)
