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
Proposed canon changes kept separate until explicit review
Deterministic continuity validation against established canon
Atomic chapter commit with accepted story changes
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: storyai
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.
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.
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. |
There is no project-delete tool and no path-based selection.
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. |
| Store proposed durable changes outside canon. |
| Mark the active draft ready for commit. |
| Atomically promote the chapter and accepted changes. |
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 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
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.pyCoverage 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
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.
Story initialization and chapter commit are transactional.
Reads, resources, prompts, validation, and search do not mutate canon.
No delete-project, delete-all, raw SQL, automatic persistence, or automatic 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, project deletion, 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.
Private story bible for fiction writers, shared with AI assistants over MCP.
Share one project context across ChatGPT, Claude, Telegram and any MCP client.
Related MCP Servers
- AlicenseCqualityDmaintenanceProvides local desktop agents with durable project memory and safety gates for writing long novels, enabling continuity management, chapter drafting, and state-aware handoffs.312MIT
- 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