story-agent
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@story-agentCreate a new fantasy story called The Glass Harbor"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
story-agent
story-agent is a local, MCP-first writing assistant backend for maintaining
long-form story continuity.
It keeps established story state in SQLite, protects unfinished writing with persistent drafts, retrieves relevant older passages with local embeddings, and gives an MCP client controlled tools for reading and updating the story. The MCP client—Codex or another compatible agent—does the creative writing and reasoning. The server does not call an LLM.
This project is still under development, but the workflows documented here are implemented and tested.
Features
Multiple isolated story projects, created and selected through chat
Transactional story initialization with metadata, a main character, and optional facts, lore, and an opening event
Canonical characters, facts, relationships, chapters, events, and lore
Persistent chapter drafts and automatic chunk-by-chunk saves
Revision-checked, user-initiated draft rewriting
Proposed canon changes kept separate until explicit review
Deterministic continuity validation against established canon
Atomic chapter commit with accepted story changes
Recoverable canonical chapter commits and explicit undo
Monotonic per-story canon revisions and compact commit receipts
Confirmed project deletion without arbitrary filesystem access
Bounded scene-context gathering for long writing sessions
Local semantic search over chapters, lore, events, and character facts
MCP tools, resources, and reusable workflow prompts
Client-independent operation over the standard MCP
stdiotransport
Related MCP server: Argon Memory
Architecture
Codex or another MCP client
|
| stdio MCP
v
story-agent MCP server
|
+-- safe project registry
| `-- selected isolated story database
+-- deterministic domain services
+-- SQLite canonical state
+-- SQLite persistent drafts and proposals
`-- local derived semantic indexMCP client: conversation, prose, story reasoning, identifying claims, producing continuity reports, and proposing durable changes.
MCP server: validation, bounded retrieval, controlled writes, transactions, and project selection.
SQLite: canonical story state and persistent draft state.
Semantic index: derived retrieval data; it is never canonical truth.
The core writing rule is:
autosave protects work
commit changes canonRequirements
Python 3.11 or newer
An MCP client supporting
stdioNode.js only for the optional MCP Inspector
Embeddings use the free local BAAI/bge-small-en-v1.5 model through
fastembed. No paid API is required. A first-time model download must be
explicitly allowed from the admin CLI; normal searches never download a model
or call an external service.
Installation
cd story-agent
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/story-agent --helpYou can replace .venv/bin/story-agent with .venv/bin/python main.py in the
CLI examples if the console command is not installed.
Connect an MCP client
The entry point is mcp_server.py. Two environment variables control storage:
STORY_AGENT_PROJECTS_DIRholds the safe project registry and each managed story's isolated database.STORY_AGENT_DATABASEis the legacy single-database fallback when no managed project is selected.
Codex configuration
Add this to ~/.codex/config.toml:
[mcp_servers.story-agent]
command = "/absolute/path/to/story-agent/.venv/bin/python"
args = ["/absolute/path/to/story-agent/mcp_server.py"]
default_tools_approval_mode = "approve"
[mcp_servers.story-agent.env]
STORY_AGENT_PROJECTS_DIR = "/absolute/path/to/story-agent/data/projects"
STORY_AGENT_DATABASE = "/absolute/path/to/story-agent/data/story_agent.db"Replace /absolute/path/to/story-agent with the repository's location on your
machine, then restart the MCP session. For MCP Inspector and second-client
setup, see
docs/mcp-clients.md.
Normal use: chat first
Normal writers do not need the terminal for story setup.
Create a story
Say:
Create a new fantasy story.The client should ask once for genuinely missing required information:
project display name
story title and premise
genre and tone
setting summary
main character name and description
Initial character facts, lore, and an opening event are optional. The client
then calls create_story_project, which creates and selects a safe isolated
database, and initialize_story, which writes the initial canon in one
transaction.
Project creation and initialization are intentionally separate. An empty project can exist before its story details are supplied. Initialization refuses to overwrite an already initialized story.
Work with multiple stories
List my stories.
Create another story called Moon Gate.
Switch to The Glass Harbor.
Which story is selected?Every project has its own SQLite database. The model receives generated project
IDs, never arbitrary filesystem paths. Creating a project selects it; listing
does not. Switching requires an explicit select_story_project call.
Selection is stored in project_registry.db, so it survives restarts. Clients
using the same STORY_AGENT_PROJECTS_DIR share the registry, current selection,
and canonical data.
Deleting a project requires its generated ID and an exact display-name confirmation. A selected project also requires an explicit selected-deletion flag; successful deletion clears selection instead of silently choosing another story.
Write a long chapter
Start chapter 1. Mara arrives at the abandoned lighthouse.
Continue with her meeting in the harbor office.
Continue, but keep the argument restrained.After every generated chunk, the client should call append_to_draft. The
complete draft remains locally stored across prompts and server restarts but is
not yet a canonical chapter.
The client can keep context bounded by using the draft summary, recent excerpt,
pending changes, focused canonical scene context, semantic retrieval, and
get_draft_segment only when an older portion is needed. It does not need to
send the entire chapter on every turn.
Finish and commit
Only explicit requests start the commit workflow:
I'm done with this chapter.
Finish chapter 1.
Commit this chapter.
Make this chapter canon.Continue, next, looks good, and okay are not commit approval.
The intended flow is:
Load the full stored draft.
Extract and validate continuity-relevant structured claims.
Present the continuity report.
Review every proposed persistent change.
Ask the user to accept or reject each proposal.
Mark the draft ready.
Commit the chapter and accepted changes in one transaction.
Read canonical state back to verify it.
A commit rolls back on failure. It cannot proceed until continuity is reviewed and every pending change has an explicit decision.
Every successful commit returns and persists a compact receipt containing the new canon revision, chapter summary, commit/version IDs, and the accepted events, facts, relationship changes, lore, and new characters that were actually applied. The receipt never duplicates the complete chapter.
Rewrite an active draft
A rewrite is performed only when the user explicitly requests one. The client
reads the current draft and its revision, produces revised text, then calls
replace_current_draft. If another autosave changed the draft meanwhile, the
stale revision is rejected instead of overwriting newer work.
Replacement changes only draft content and its optional summary. It does not modify or commit canon. Existing pending proposals are retained and reported for re-review because rewritten prose may no longer support them.
Undo a chapter commit
Every successful commit_draft stores a canonical snapshot from immediately
before that commit. To undo, the client first calls get_story_versions, shows
or resolves the latest version, and calls undo_last_commit with that expected
version ID after explicit user intent.
Undo restores the complete structured canon transactionally. Draft state is separate and is not restored. Derived semantic chunks are removed, ensuring rolled-back content cannot appear in search; rebuild the semantic index before using semantic retrieval again.
An undone receipt remains in SQLite as historical audit metadata but is marked
inactive with its undo revision and timestamp. get_recent_canon_changes
returns only active receipts, so an undone commit never appears to be current.
Canon revisions and commit receipts
Each story database has a monotonic canon_revision. Canonical domain
transactions advance it exactly once; draft autosaves, rewrites, proposal
storage, and read operations do not. Undo also advances the revision because it
creates a new, intentionally restored canonical state rather than moving the
counter backward.
Commit receipts are deterministic audit and retrieval aids generated from already-approved structured proposals and their actual write outcomes. They are not model memory and are not an alternative source of truth. Exact characters, relationships, timeline events, lore, and chapters must still be read from their canonical tables.
At the beginning of a new session, an MCP client can call
get_recent_canon_changes to recover a bounded view of recent durable changes
without rereading full chapters.
Canon versus drafts
Canonical state contains story metadata, characters, explicit facts, relationships, committed chapters, timeline events, and lore.
Draft state contains an in-progress or ready chapter, its full autosaved text, a bounded summary, and proposed new characters, facts, relationships, lore, and events. Saving a draft never changes canonical story state. Proposals remain pending until explicit review during commit.
Continuity checking
draft prose
-> client identifies structured claims
-> server compares claims with canonical SQLite state
-> client writes the final continuity reportThe validator supports character existence, character facts, explicit
knowledge, relationship state, event order, chapter existence, and lore
content. Results are confirmed, contradicted, or unknown. Missing canon is
unknown, not an error. Knowledge checks use explicit facts such as Knows: ...
and Does not know: ....
The server does not interpret raw prose, rewrite drafts, or persist corrections. Those reasoning and writing decisions remain with the MCP client.
Exact and semantic retrieval
Use exact tools for authoritative identities, facts, relationships, chronology,
chapter numbers, and lore. Use semantic search to locate unstructured passages
whose wording differs from the query. For example, a search for Alex distrusts authority can retrieve a passage where Alex avoids a commander and refuses an
officer's orders.
Semantic sources include chapter content and summaries, lore passages, event descriptions, and character facts. Results contain traceable source metadata. Similarity is only a lead; verify important structured claims with exact tools.
The index is derived and can always be rebuilt from canonical SQLite state:
.venv/bin/story-agent --database data/my-story.db search-index-rebuild
# Permit the first local model download when needed:
.venv/bin/story-agent --database data/my-story.db \
search-index-rebuild --allow-model-download
.venv/bin/story-agent --database data/my-story.db search-index-status
.venv/bin/story-agent --database data/my-story.db \
semantic-search "Alex distrusts authority" --limit 5
.venv/bin/story-agent --database data/my-story.db \
semantic-search "the red stone" \
--source-type chapter --source-type loreMCP interface
Project tools
Tool | Purpose |
| List registered projects. |
| Create an isolated empty project and select it. |
| Switch explicitly to a registered project ID. |
| Report selection and initialization state. |
| Permanently delete a confirmed registered project. |
There is no path-based project selection or generic file-delete tool.
Canonical read and validation tools
Tool | Purpose |
| Read a character and facts by name. |
| Read one canonical chapter by number. |
| Read bounded recent chapters. |
| Read events with optional chapter bounds. |
| Perform case-insensitive exact lore search. |
| Read a relationship between two characters. |
| Gather bounded characters, relationships, chapters, events, and lore. |
| Locate semantically related canonical passages. |
| Compare structured claims with canon. |
| Validate a client-authored proposal without saving it. |
Setup and draft tools
Tool | Purpose |
| Atomically create metadata and initial canon. |
| Read bounded story, chapter, draft, and proposal status. |
| Read bounded active-draft context. |
| Read one bounded part of the full draft. |
| Create or replace an in-progress draft. |
| Append a chunk and autosave it. |
| Replace draft text with optimistic revision checking. |
| Store proposed durable changes outside canon. |
| Mark the active draft ready for commit. |
| Atomically promote the chapter and accepted changes. |
| List bounded canonical commit-version metadata. |
| Read recent active compact commit receipts. |
| Restore canon to before the latest commit. |
Pending change types are new_character, character_fact, relationship,
lore, and event. Each requires a short evidence excerpt.
Controlled canonical writes
Tool | Purpose |
| Create a canonical character. |
| Save canonical chapter text directly. |
| Add a canonical timeline event. |
| Add an explicit canonical character fact. |
| Create or update a canonical relationship. |
| Add a canonical lore entry. |
These remain useful for administration and explicitly approved changes. Normal chapter writing should use drafts and reviewed commit.
Resources
URI | Content |
| Story overview, latest chapter, and bounded state. |
| Bounded canonical character directory. |
| Bounded recent canonical timeline. |
| Metadata and bounded chapter content. |
| Description and bounded character facts. |
Resources are concise and read-only.
Reusable prompts
Prompt | Purpose |
| Context retrieval, chunked writing, autosave, review, and commit workflow. |
| Evidence-based continuity review without mutation. |
| Review proposed canon changes before writes. |
Prompts are declarative instruction templates returned to the client. They do not call a model or execute tools themselves. Presentation varies by client: a prompt may appear as a menu item, slash command, API feature, or an instruction an agent chooses during conversation.
Admin and development CLI
The CLI is optional and works with an explicit database path. Put --database
before the command:
.venv/bin/story-agent --database data/my-story.db COMMANDDifferent unmanaged stories should use different files. Multi-project chat use is managed through MCP, not these direct CLI paths.
Setup, status, and drafts
# Terminal setup fallback; refuses to overwrite an initialized story
.venv/bin/story-agent --database data/my-story.db init
.venv/bin/story-agent --database data/my-story.db status
.venv/bin/story-agent --database data/my-story.db schema-status
.venv/bin/story-agent --database data/my-story.db draft
.venv/bin/story-agent --database data/my-story.db \
draft --start 0 --max-characters 4000
.venv/bin/story-agent --database data/my-story.db \
draft-append 1 "Chapter title" "New chapter text"
.venv/bin/story-agent --database data/my-story.db \
draft-append 1 "Chapter title" "New chapter text" \
--summary "Summary so far"
.venv/bin/story-agent --database data/my-story.db draft-ready
.venv/bin/story-agent --database data/my-story.db \
commit --continuity-reviewed
# Every pending ID must be decided
.venv/bin/story-agent --database data/my-story.db \
commit --continuity-reviewed \
--accept-change 1 --accept-change 2 --reject-change 3
# Does not remove canonical chapters
.venv/bin/story-agent --database data/my-story.db discard-draftDirect canonical commands
# Characters and facts
.venv/bin/story-agent --database data/my-story.db \
character-create "Alex" --description "A reluctant courier"
.venv/bin/story-agent --database data/my-story.db character-get 1
.venv/bin/story-agent --database data/my-story.db fact-add 1 "Fears the tribunal"
.venv/bin/story-agent --database data/my-story.db fact-list 1
# Chapters
.venv/bin/story-agent --database data/my-story.db \
chapter-save 1 "Arrival" "Chapter content"
.venv/bin/story-agent --database data/my-story.db chapter-get 1
.venv/bin/story-agent --database data/my-story.db chapter-list
# Timeline timestamps require a timezone
.venv/bin/story-agent --database data/my-story.db \
event-add "Alex reaches the city" "2040-01-01T12:00:00+00:00" \
--chapter-id 1 --character-id 1
.venv/bin/story-agent --database data/my-story.db timeline
# Relationships
.venv/bin/story-agent --database data/my-story.db \
relationship-save 1 2 "distrustful" \
--description "They suspect each other"
.venv/bin/story-agent --database data/my-story.db relationship-get 1 2
# Lore
.venv/bin/story-agent --database data/my-story.db \
lore-create "Red Stone" "The relic glows near broken oaths"
.venv/bin/story-agent --database data/my-story.db lore-search "relic".venv/bin/story-agent --help
.venv/bin/story-agent commit --helpCross-client test
To prove state belongs to the backend rather than one agent:
Configure two clients to launch the same
mcp_server.py.Give both the same
STORY_AGENT_PROJECTS_DIR.Create or select a disposable test project.
Add a harmless character fact from client A.
Read it from client B.
Add another fact from client B and read it from client A.
The clients need not run simultaneously. Sharing only the source code is not enough; they must share the project registry directory. Tested Inspector commands are in docs/mcp-clients.md.
Tests
Synthetic scale fixtures
The developer-only generator creates a new, clearly marked test project in the configured project registry. It never overwrites an existing project and needs no LLM, API key, or network access:
.venv/bin/python -m tools.generate_test_story --project-name scale-100 \
--chapters 100 --characters 30 --facts-per-character 10 \
--events-per-chapter 3 --relationships 75 --lore 50 \
--words-per-chapter 2500 --seed 42Use --with-active-draft to leave an uncommitted next chapter. --build-index
uses the normal semantic-index rebuild path and requires the embedding model to
be cached locally; it never downloads a model. The output reports the project
ID, counts, seed, and index state. Configuration has per-field and total-size
limits (--help lists the arguments). The generator uses production domain
writes to make a canonical end-state fixture; it deliberately does not simulate
chapter-by-chapter commit receipts or undo history. Use the existing commit
workflow tests for those behaviors.
Backend benchmarks
Run the offline benchmark against disposable generated projects, or a temporary SQLite copy of an existing registered synthetic project:
.venv/bin/python -m tools.benchmark_story_agent --preset all \
--iterations 7 --warmup 2 --json benchmark-results.json
.venv/bin/python -m tools.benchmark_story_agent --project-id story_... \
--compare benchmark-results.jsonPresets contain 5, 50, and 120 chapters. The harness uses the locally cached
FastEmbed model and never downloads one. The report gives median, mean, min,
max, and p95 milliseconds; JSON also retains every sample. --json creates a
new file and refuses to overwrite one. Optional --warn-ms OPERATION=MS and
--warn-percent PERCENT annotate results without failing the benchmark.
Preparation and project cloning are excluded from measured operation times.
"Cold" means the first call in the current process; OS file caches are not
flushed. The adapter measurements invoke Python MCP adapter helpers, not the
stdio transport, so they should not be read as full client round-trip latency.
Draft and commit tests run only on temporary copies; every measured commit is
undone on its own copy. Ordinary story projects are rejected by --project-id.
Run service/application and MCP transport tests separately:
.venv/bin/python -m pytest -q --ignore=tests/test_mcp_transport.py
.venv/bin/python -m pytest -q tests/test_mcp_transport.pyRun the long-story correctness suite explicitly:
.venv/bin/python -m pytest -q -m long_story
# Explicitly exclude the optional real-model check
.venv/bin/python -m pytest -q -m 'long_story and not local_embedding'Normal runs exclude long_story. Its fixed 5-, 50-, and 120-chapter fixtures are
generated once per test session, with a separate SQLite copy for each test.
The suite covers old character/event retrieval, relationship history, bounded
scene context, draft recreation, commit/undo/recommit, restarts, two large
isolated projects, migrations, and broken-reference detection. The terminal
summary records fixture counts. Deterministic concept vectors check search
contracts. The cached FastEmbed check is opt-in with
STORY_AGENT_TEST_LOCAL_EMBEDDINGS=1 and skips if its model is unavailable;
it requires additional memory and never downloads a model. Document embeddings
use batches of 32 rather than FastEmbed's default 256 to bound inference memory.
Canon-revision
compare-and-set writes are not implemented, so that capability is explicitly
skipped; draft revision conflicts and stale semantic indexes are tested.
Starting a discarded draft again, or starting an undone chapter again, clears the prior draft proposals and continues the draft revision counter. Accepted canon must be reviewed again before recommit. Opening a database detects invalid canonical references or required story metadata; semantic search reports an invalid index if its chunks contain missing sources or invalid vector shapes.
Coverage includes initialization and rollback, canonical services, autosave, atomic commit, proposals, continuity, semantic retrieval, resources, prompts, project isolation, persistent selection, and MCP transport discovery.
Data safety
Native ZIP backup and restore
Backup/import are local CLI operations, not MCP file-path tools:
story-agent backup-create moon-gate.zip
story-agent backup-create moon-gate.zip --project-id STORY_PROJECT_ID
story-agent import-backup moon-gate.zip
story-agent import-backup moon-gate.zip --json
# Optional synchronous rebuild using the already-cached local embedding model:
story-agent import-backup moon-gate.zip --rebuild-indexThe registry root follows STORY_AGENT_PROJECTS_DIR, as with MCP. Export uses
the selected project unless an ID is given, and refuses an existing output file.
The ZIP v1 format contains exactly manifest.json and story.sqlite. The manifest
records container/schema versions separately, original project ID, display name,
title, creation time, component flags, optional application version, and the
database's SHA-256 checksum. Drafts (including pending changes), canon revision,
and commit/undo history are included. Vectors are deliberately omitted. Backups
contain private story/draft content; do not commit them to a public repository.
Import validates archive names, duplicates, links, compression/size limits, manifest, checksum, native schema objects, canonical references, drafts, and historical snapshots. Only the fixed database member is written to a controlled temporary directory; arbitrary ZIP paths are never extracted. Limits are 512 MiB for the database/archive (plus a 64 KiB manifest) and a 1000:1 compression ratio. Custom database views, virtual tables, and non-native triggers are unsupported. Checksums detect damage, not authenticity: restore only backups you trust.
Older supported databases migrate on the temporary copy. Newer schemas or
container versions are rejected. Registration happens only after validation,
using a fresh generated project ID and a duplicate-safe name such as
Moon Gate (Imported). Existing databases and selection are untouched, even if
index rebuilding or final validation fails. After import, explicitly select
the returned ID in chat. Canon revision is preserved, not reset. Imported draft
text remains non-canonical, and compatible version history retains undo support.
If component flags indicate omitted drafts/history, their corresponding tables
must be empty; no missing history or structured canon is fabricated.
Rebuilding is off by default: missing retrieval is a nonfatal health warning.
Use the normal index rebuild command afterward, or request --rebuild-index.
No model download or hidden API call occurs. A requested rebuild failure rejects
the import; retry without it to restore canon first. Normal failures clean up the
unpublished project copy; a hard crash may leave an unregistered managed file,
but never selects it or overwrites another project. This phase does not support
Markdown, TXT, EPUB, or arbitrary novel-to-canon extraction.
Project health / doctor
In chat, ask for project health. The read-only MCP tool
get_project_health(project_id=None) inspects the selected story or one
registered project without switching it. It reports schema, canon revision and
references, active draft metadata, semantic index health, and undo availability.
An active draft is normal and does not lower health.
story-agent doctor
story-agent doctor --project-id STORY_PROJECT_ID
story-agent doctor --json
story-agent doctor --deep
# Explicit single-database developer fallback:
story-agent --database data/my-story.db doctorStatuses: healthy means the checked metadata is consistent; warning covers
missing optional retrieval, empty setup, or migration needed; degraded covers
stale/invalid retrieval or recoverable draft/version problems; invalid covers
incompatible/unreadable canon or broken canonical references. Results contain
machine-readable codes and recommended actions. safe_to_continue is false for
core corruption, incompatible schema, missing selection, and pending migration;
it is not canon approval or a guarantee about uninspected prose.
Standard checks use read-only metadata/count/reference queries. They do not load
chapter bodies, vectors, full snapshots, or an embedding model. Snapshot checks
are explicitly header_only; index checks are metadata. --deep additionally
checks SQLite integrity, the latest available undo snapshot's shape/references,
and full index checksums and source contents. Neither mode repairs, migrates,
rebuilds, creates a registry/database, or changes selection. Diagnostics target
one project; they do not sweep every registered project or validate every
historical snapshot. An older schema is reported without migrating it.
Semantic index recovery
The semantic index is disposable derived data in each story's SQLite database. Canonical tables, drafts, and undo snapshots do not depend on it. Schema v5 adds an index manifest: registered project ID (or no binding for standalone admin databases), schema/index/chunking versions, source count, source and vector digests, build completion, timestamps, and indexed canon revision. Model, dimension, chunk count, and text-change revision remain in index state.
search-index-status reports health: fresh, missing, stale, building,
or invalid, plus rebuild_required. Legacy state values ready and
unbuilt remain for compatibility. Missing/stale/invalid search returns
ok: false, a semantic_index_* error, and no results. Reads never rebuild
automatically or download a model.
Rebuild a registered project without changing the selected project:
.venv/bin/story-agent search-index-status --project-id STORY_PROJECT_ID
.venv/bin/story-agent search-index-rebuild --project-id STORY_PROJECT_IDReplace STORY_PROJECT_ID with an ID returned by list_story_projects.
The existing --database admin option also remains available. Use --model
on rebuild to change models; --allow-model-download is an explicit opt-in.
Rebuilds stage batches of 32 embeddings in temporary SQLite storage. They validate dimensions, finite vectors, counts, and digests before replacing all cache tables and metadata in one transaction. Failure preserves the old cache; concurrent canon changes reject promotion. Search checks source mappings, checksums, configuration, and canonical chunk content before returning results. An old valid cache stays available during staging; partial staging data is never published. Temporary build storage is removed on normal success/failure; a process crash may leave unused temporary files, never promoted results.
Canon writes make the index stale; undo removes vectors; draft rewrites do not
invalidate it. Schema v5 migration requires rebuilding older indexes without
changing canon. Project deletion removes its database and index together.
Copying/importing a database into a different registered project requires a
rebuild. There is currently no product import command. Removing all three
semantic_* cache tables is recoverable through rebuild; corruption of the
entire SQLite file still requires normal database backup recovery.
Recovery tests use deterministic test vectors, not a real model quality claim:
.venv/bin/python -m pytest -q tests/test_index_recovery.py
.venv/bin/python -m pytest -q -m long_storyStory databases record their schema version with SQLite PRAGMA user_version.
New databases start at the current version. Existing, recognized story-agent
databases migrate in order when selected or opened; listing projects only
inspects their versions and does not migrate them. Before migration, the server
creates a .schema-vN.*.bak SQLite backup beside the story database. A failed
migration rolls back without advancing the version. Databases from a newer
story-agent version are refused, never downgraded.
The optional schema-status CLI command reports the database version, the
application version, and whether migration is needed without changing the
database. Semantic vectors are derived data: migrations that change their
layout invalidate the index, which can be rebuilt with search-index-rebuild.
Story undo restores canonical content, not the database schema, so it cannot
reverse a schema migration.
Project filenames use random internal IDs, not user input.
Selection accepts only registered, validated project IDs.
MCP responses do not expose full internal database paths.
Duplicate display names are rejected case-insensitively.
Project creation never overwrites an existing database.
Project deletion requires ID, display-name confirmation, and extra intent for the selected project.
Story initialization and chapter commit are transactional.
Canonical undo validates the expected latest version and restores atomically.
Failed commits create neither a receipt nor a revision increment.
Draft replacement rejects stale revisions.
Reads, resources, prompts, validation, and search do not mutate canon.
No delete-all, raw SQL, automatic canon persistence, or automatic draft rewrite interface exists.
Back up STORY_AGENT_PROJECTS_DIR to preserve managed stories. For an unmanaged
CLI story, back up its .db file. Do not manually edit project_registry.db or
move its story databases independently.
Troubleshooting
The MCP server is not visible
Check that the configured Python and
mcp_server.pypaths are absolute.Confirm dependencies are installed in
.venv.Restart the MCP session after configuration changes.
mcp_server.pyspeaks protocol messages over standard I/O; it is not an interactive terminal program.
Two clients see different stories
Ensure both use exactly the same STORY_AGENT_PROJECTS_DIR, then inspect the
selection with get_current_story_project.
Initialization is rejected
Initialization needs a selected empty project. Create one first. An initialized project cannot be overwritten; create or select another project.
Semantic search is unavailable or stale
Run search-index-status, then rebuild the affected story's index. Add
--allow-model-download only when you intentionally permit the local model
download.
A draft will not commit
Confirm that the draft is ready, continuity was reviewed, every pending change was accepted or rejected, and referenced canonical entities are valid. A failed commit should leave the draft and canon unchanged.
Project layout
story-agent/
├── database.py # SQLite schema and connection boundary
├── models.py # Domain models
├── main.py # Admin/development CLI
├── mcp_server.py # Thin MCP interface
├── services/
│ ├── story_service.py # Canonical operations
│ ├── workflow_service.py # Setup, drafts, proposals, atomic commit
│ ├── project_service.py # Multi-story registry and selection
│ ├── continuity_service.py # Structured claim checks
│ ├── proposal_service.py # Proposal validation
│ └── retrieval_service.py # Chunking, embeddings, semantic search
├── tests/
├── docs/mcp-clients.md
└── data/Current boundaries
The project intentionally has no hidden/server-side LLM, paid embedding API, GUI, automatic planning, automatic draft rewriting, automatic canon promotion, raw filesystem/SQL access, destructive reset, or autonomous background behavior. Structured canon remains authoritative; embeddings only support retrieval.
License
See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Project management shared by people and AI agents, with persistent project state through MCP.
- mcpOAuthco.aistoryhub
Remote MCP server for AIStoryHub: stories, chapters, story bible, Voiceprints, AI generation.
- AnthraOAuthcom.anthra
Agentic AI book creator: plan, write, illustrate, narrate, and publish books from any MCP client.
Share one project context across ChatGPT, Claude, Telegram and any MCP client.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables writers and AI agents to preserve continuity in long-form fiction by maintaining a narrative knowledge graph and exposing MCP tools for querying outlines, entities, references, and consistency diagnostics.14MIT
- AlicenseNot gradedqualityAmaintenanceEnables MCP agents to maintain durable, evidence-aware project knowledge, retrieve precise excerpts on demand, and track decisions, conflicts, and revisions across sessions.1Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables multiple MCP-compatible AI clients to share persistent, versioned project knowledge across sessions with conflict-safe updates, provenance, hybrid retrieval, stale-memory handling, and context-budgeted recall.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI-driven long-form novel creation and management, including chapter generation, character and timeline tracking, semantic memory retrieval, version savepoints, and deep consistency checking across multiple projects through MCP tools, with support for local LM Studio or any OpenAI-compatible API.15MIT