https://github.com/hannasdev/mcp-writing
MCP service for AI-assisted reasoning and editing on long-form fiction projects
https://github.com/hannasdev/mcp-writing
Last synced: 22 days ago
JSON representation
MCP service for AI-assisted reasoning and editing on long-form fiction projects
- Host: GitHub
- URL: https://github.com/hannasdev/mcp-writing
- Owner: hannasdev
- License: agpl-3.0
- Created: 2026-04-12T13:30:33.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-26T09:00:12.000Z (2 months ago)
- Last Synced: 2026-04-26T09:32:59.159Z (2 months ago)
- Language: JavaScript
- Size: 607 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Maintainers: MAINTAINERS.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# mcp-writing
[](https://github.com/hannasdev/mcp-writing/actions/workflows/ci.yml) [](https://github.com/hannasdev/mcp-writing/releases) [](https://www.npmjs.com/package/@hanna84/mcp-writing) [](https://www.npmjs.com/package/@hanna84/mcp-writing) [](https://nodejs.org/) [](https://www.gnu.org/licenses/agpl-3.0)
An MCP service for AI-assisted reasoning and editing on long-form fiction projects.
Designed to work with [OpenClaw](https://github.com/openclaw/openclaw) but compatible with any MCP-capable AI gateway.
## Quick launch
For local stdio MCP clients, run the published package directly:
```sh
WRITING_SYNC_DIR=/path/to/sync-dir DB_PATH=./writing.db npx -y @hanna84/mcp-writing
```
The CLI wrapper defaults to stdio transport and adds the Node 22 SQLite flag automatically when needed.
## VS Code extension
For VS Code-native setup flows (including prose styleguide setup), use:
- [hannasdev/mcp-writing-vscode](https://github.com/hannasdev/mcp-writing-vscode)
## What it does
Instead of feeding an entire manuscript to an AI and hoping it fits in the context window, `mcp-writing` builds a structured index from your scene files. The AI queries that index first — finding relevant characters, beats, and loglines — then loads only the specific prose it needs.
**Current status:**
- **Core platform complete:** Metadata-first analysis, SQLite-canonical structural and relationship metadata, compatibility sidecar maintenance, AI-assisted prose editing with confirmation + git history, review bundles, and Scrivener Direct extraction are all implemented.
- **Recently completed:** Relationship Metadata Boundary closed the sidecar-first scene relationship mutation path, added SQLite-first paired and one-sided evidence workflows, and preserved legacy sidecar/frontmatter compatibility for sync and import.
- **Active development:** No initiative is currently selected.
- **Deferred backlog:** OpenClaw integration, client-agnostic setup, divisions, and embeddings search.
- **Ideas and open questions:** tracked separately so future exploration does not distort the active roadmap.
## Who it is for
- Novelists and writing teams working on long manuscripts with many scenes, characters, and continuity constraints.
- AI-assisted editing workflows where you want targeted context retrieval instead of full-manuscript prompting.
- Projects that need traceable, reversible edits with metadata that stays synchronized as drafts evolve.
## Documentation
| Guide | Description |
|---|---|
| [docs/guides/setup.md](docs/guides/setup.md) | Prerequisites, first-time setup, Scrivener import, native sync format |
| [mcp-writing-vscode](https://github.com/hannasdev/mcp-writing-vscode) | VS Code extension for client-native setup flows |
| [docs/guides/docker.md](docs/guides/docker.md) | Docker Compose, deployment operations, MCP gateway notes |
| [docs/guides/backup-recovery.md](docs/guides/backup-recovery.md) | Project backup artifacts, diagnostics, and explicit restore workflow |
| [docs/guides/sidecar-compatibility.md](docs/guides/sidecar-compatibility.md) | Sidecar compatibility roles, migration posture, and daily-work authority boundaries |
| [docs/foundations/managed-structure-contract.md](docs/foundations/managed-structure-contract.md) | Design boundaries for structural mutation, generated views, import, and maintenance workflows |
| [docs/agents/tools.md](docs/agents/tools.md) | Full tool reference — auto-generated from source |
| [docs/agents/README.md](docs/agents/README.md) | Index of agent-focused guidance, examples, and boot files |
| [docs/agents/use-cases.md](docs/agents/use-cases.md) | Agent-oriented transcripts and prompt/tooling examples |
| [docs/guides/development.md](docs/guides/development.md) | Running locally, tests, environment variables, troubleshooting |
## Breaking changes
### `describe_workflows` surface redesign
`describe_workflows` now exposes an outcome-first, discovery-first workflow map. This was a breaking change if your prompts or automation depend on previous workflow IDs or ordering; the newer `recommended_next_actions` tier is additive and appears before the full catalogue.
Update integrations using this mapping:
- `manuscript_exploration` -> `question_driven_discovery` (or `targeted_scene_reading` when the task is prose inspection)
- `prose_editing` -> `safe_scene_revision`
- `character_management` -> `character_understanding`
- `place_management` -> `place_understanding`
- `review_bundle` -> `review_preparation`
New workflow IDs added:
- `thread_understanding`
- `parity_recovery`
Styleguide workflows are still available, but no longer positioned as part of the primary daily workflow surface.
### `find_scenes` and `get_arc` response-shape standardization
`find_scenes` and `get_arc` now always return structured envelopes, including non-paginated calls.
- Envelope fields: `results`, `total_count`.
- Pagination fields are included when paging is active.
- `warning` / `next_step` are included when relevant.
If your integration previously handled raw arrays for non-paginated calls, update it to parse envelopes consistently.
Safe parsing pattern:
```js
const parsed = JSON.parse(toolText);
if (parsed.ok === false) throw new Error(parsed.error?.message ?? "tool error");
const scenes = parsed.results ?? [];
const totalCount = parsed.total_count ?? scenes.length;
const warning = parsed.warning ?? null;
const nextStep = parsed.next_step ?? null;
```
### `get_character_sheet`, `get_place_sheet`, `list_scene_references`, `get_relationship_arc` response-shape standardization
These metadata-read tools now return structured envelopes instead of flat objects or raw arrays.
- `get_character_sheet` and `get_place_sheet`: previously returned a flat object of field values; now return `{ results: [row], total_count: 1, next_step }`.
- `list_scene_references`: previously returned `{ references, scene_id, project_id }`; now returns `{ results, total_count, scene_id, project_id }`.
- `get_relationship_arc`: previously returned a raw JSON array; now returns `{ results, total_count, from_character, to_character }`.
Safe parsing pattern for sheet tools:
```js
const parsed = JSON.parse(toolText);
if (parsed.ok === false) throw new Error(parsed.error?.message ?? "tool error");
const sheet = parsed.results?.[0] ?? {};
const nextStep = parsed.next_step ?? null;
```
Safe parsing pattern for list/arc tools:
```js
const parsed = JSON.parse(toolText);
if (parsed.ok === false) throw new Error(parsed.error?.message ?? "tool error");
const items = parsed.results ?? [];
const totalCount = parsed.total_count ?? items.length;
```
## Usage scenarios
### 1) Continuity pass before sending chapters to beta readers
Goal: catch inconsistencies before sharing pages.
1. Run `sync` after your latest writing session.
2. Ask `find_scenes` for scenes involving a specific character or tag (for example, all scenes tagged `injury` or `promise`).
3. Use `get_arc` to review that character's ordered progression across the manuscript.
4. Load only the suspect scenes with `get_scene_prose`.
5. Attach follow-up notes with `flag_scene` where continuity needs a fix.
Outcome: you review one narrative thread at a time instead of rereading the entire novel to find contradictions.
### 2) Planning and tracking subplot beats during revisions
Goal: make sure subplot threads progress intentionally and resolve on time.
1. Run `list_threads` for the project.
2. Use `get_thread_arc` to inspect scene order and beat labels for each thread.
3. When a beat is missing, call `track_thread_arc` to add or update it on the right scene.
4. Re-run `get_thread_arc` to confirm pacing and coverage.
Outcome: subplot structure stays visible and auditable, which reduces dropped threads in late drafts.
### 3) Tightening scene metadata after heavy prose edits
Goal: keep indexes accurate without manually re-tagging everything.
1. After rewriting scenes, call `enrich_scene` to re-derive lightweight metadata from current prose.
2. Use `update_scene_metadata` for intentional editorial fields (for example, beat, POV, status, and tags). It rejects scene `characters` and `places`; use `connect_character_place_evidence` when a scene proves paired sheet-backed character/place evidence, `connect_scene_character_evidence` for character-only evidence, and `connect_scene_place_evidence` for place-only evidence. Those relationship evidence tools prefer canonical IDs but also accept unambiguous scene titles, character names, place names, and case variants; ambiguous or suggested-only matches fail without mutating state. Use `audit_relationship_metadata` for retained sidecar/frontmatter relationship fields. Use `list_chapters` plus `assign_scene_to_chapter` or `move_scene` for chapter placement and ordering.
3. Use `search_metadata` for keyword/FTS metadata searches across indexed titles, loglines, tags, characters, places, and versions, and use `find_scenes` to verify scenes are discoverable under structured filters. After identifying likely scenes, use `get_scene_prose` for prose context.
Outcome: your AI assistant can reliably find the right scenes without drifting from the manuscript.
### 4) Safe AI-assisted line edits with rollback
Goal: let AI propose prose edits without losing control of your draft.
1. Ask the AI to call `propose_edit` for a specific scene.
2. Review the staged diff.
3. Accept with `commit_edit` or reject with `discard_edit`.
4. Use `list_snapshots` (and optional `snapshot_scene`) to inspect or preserve revision history.
Outcome: you get AI speed with explicit approval and recoverable history for every applied change.
### 5) Refreshing scene-character links after imports or major rewrites
Goal: rebuild scene-to-character links in a controlled way after imported prose changes or metadata drift.
1. Start with `enrich_scene_characters_batch` using the default `dry_run=true` to preview inferred links for a project, chapter, or explicit scene list.
2. Poll `get_async_job_status` until the batch job completes, then review `job.result.results` for changed scenes, ambiguous matches, and partial failures.
3. Spot-check a few affected scenes with `get_scene_prose` if the changes touch important continuity or cast-heavy chapters.
4. Re-run `enrich_scene_characters_batch` with `dry_run=false` once the preview looks correct.
5. If you want a destructive overwrite instead of additive merge behavior, use `replace_mode=replace` with `confirm_replace=true` deliberately.
Outcome: character-link maintenance becomes a preview-first relationship repair operation instead of a one-off regex script or manual sidecar cleanup.
### 6) Post-upgrade recovery after legacy migration warnings
Goal: recover index confidence quickly when legacy upgrade warnings indicate ambiguous rows were skipped.
1. Start by checking `get_runtime_config` (or `describe_workflows`) and confirm whether `db_migration_warnings` contains `LEGACY_JOIN_ROWS_SKIPPED`.
2. If present, run `sync` immediately to rebuild scene relationships from compatibility sidecars and prose metadata.
3. Continue normal discovery (`find_scenes`, `get_arc`, `get_thread_arc`) and watch for stale-metadata warnings.
4. When you touch stale scenes, run `enrich_scene(scene_id, project_id)` to recover metadata parity incrementally.
5. If many scenes remain stale, switch to `enrich_scene_characters_batch` (dry-run first) for broader catch-up.
Outcome: upgrade-related data loss risk becomes an explicit, operator-visible recovery workflow instead of a silent state mismatch.
## License
AGPL-3.0-only