Skip to content

Repository files navigation

ABook — Agentic AI Book Writing

License: MIT Docker Hub .NET

A self-hosted web application that uses AI agents to collaboratively write books. Seven specialized agents — Story Bible, Characters, Plot Threads, Chapter Outlines, Writer, Checker, and Editor — work together under your direction, streaming their progress in real time and pausing to ask clarifying questions when needed.


Features

Writing pipeline

  • Seven specialized agents across two phases: a 4-phase Planner (Story Bible → Characters → Plot Threads → Chapter Outlines) and a per-chapter writing pipeline (Pre-write Check → Write → Check → Edit)
  • Checker → mechanical patch apply — the Checker flags continuity, grammar, repetition, and style issues as structured JSON patches; the Editor applies them mechanically (no LLM call) using indexed text matching with whitespace normalization and position hints
  • Full synopsis spine — every prior chapter's title and outline is injected into Writer and Editor messages so agents stay aware of the whole narrative and avoid recycling beats or re-introducing established characters
  • RAG context retrieval — Writer runs 3 targeted queries (characters, locations, plot threads) and Editor runs 4 (same + repeated-phrase detection) against pgvector embeddings

Planning & guidance

  • Guided planning Q&A — agents ask clarifying questions up front before planning begins, then carry your answers through all four planning phases
  • Human-assisted generation — pauses after each planning phase, and after each chapter's mechanical fixes so you can edit the book and steer the creative rewrite; pending questions are restored after page refresh; supports Ctrl+Enter to submit
  • Flexible workflow controlsPlan Only, Write Book, Continue, Continue Planning, and individual per-chapter agent buttons; Stop cancels any running agent cleanly
  • Interrupted runs keep their output — if a Characters, Plot Threads, or Chapter Outlines run times out, drops, or is stopped part-way, everything that finished streaming is saved instead of discarded; run the phase again to pick up where it left off
  • Re-runs build on what exists — regenerating a planning phase sends the current characters, plot threads, or outlines back to the model to refine and extend, rather than starting from a blank page; archived items stay out of it and are never overwritten

Content management

  • Story Bible, Characters & Plot Threads — generated by the Planner, fully editable, with per-item version history and snapshot restore
  • Inline editing — edit book metadata, chapter titles/outlines, and add chapters manually without leaving the detail page
  • Version history — chapters, characters, and plot threads all track history with preview and restore; soft-archive instead of delete
  • Archived means archived — an archived chapter, character, or plot thread is kept purely so you can look at it or restore it. It is never sent to a model, never counted in planning or continuity checks, never included in an HTML/FB2/EPUB export or on the public reader page, and agents refuse to write to it
  • Book continuation — create a sequel that copies all settings and inherits ancestor context; RAG and planning reference the full base-book chain

Exports & sharing

  • Multiple export formats — HTML (6 colour themes, adjustable font size), EPUB, FB2, and a Metadata document (book info, outlines, planning artifacts, agent messages, token stats)
  • Public Library — browse and read published books without logging in (when public mode is enabled); each chapter has its own URL for bookmarking and sharing

Infrastructure

  • Pluggable LLM backend — Ollama (default, local), OpenAI (or any OpenAI-compatible API), or Google AI Studio; configurable globally, per-user, or per-book
  • Real-time streaming — watch chapters being written token by token via SignalR; planning phases stream with live progressive JSON previews
  • Token usage statistics — per-agent prompt and completion token counts, persisted to the database and displayed in a collapsible panel. Calls that error, time out, or are cancelled are recorded too, with a Status column and the failure reason shown next to their partial counts
  • MCP server — built-in Model Context Protocol server at /mcp; connect Claude Desktop, VS Code Copilot, or any MCP client using a per-user API token
  • Multi-user — cookie-based authentication with admin role for user management
  • Ollama model management — browse installed models, pull new ones with live progress
  • Global concurrency limit — cap simultaneous agent runs across all books/users with AgentSettings__MaxConcurrentRuns
  • PWA support — installable, works offline for cached content

Architecture

[React SPA — served as static files from ASP.NET wwwroot]
        ↕ REST API + SignalR
[ASP.NET Core 10 API]
        ↕ Direct provider SDKs      ↕ EF Core 10 + Npgsql
[LLM (Ollama / OpenAI / Google)]   [PostgreSQL 16 (pgvector in-DB)]

React is built at image-build time and served from wwwroot/ — there is no separate frontend container at runtime.


Quick Start

Prerequisites

Run with Docker Compose

docker-compose up -d

# App is available at
open http://localhost:5000

On first launch the app shows a Create Admin Account setup screen — the first account registered automatically becomes admin. After signing in, go to Settings to configure your LLM provider and pull an Ollama model.

Run from Docker Hub

docker run -d \
  -p 5000:8080 \
  -e ConnectionStrings__DefaultConnection="Host=<postgres-host>;Port=5432;Database=abook;Username=abook;Password=abook" \
  --add-host host.docker.internal:host-gateway \
  jncchds/abook:latest

PostgreSQL with the pgvector extension must be reachable. The compose file below starts it automatically.

Full docker-compose.yml
services:
  abook-api:
    image: jncchds/abook:latest
    ports:
      - "5000:8080"
    environment:
      - ConnectionStrings__DefaultConnection=Host=postgres;Port=5432;Database=abook;Username=abook;Password=abook
      - ASPNETCORE_ENVIRONMENT=Production
    depends_on:
      postgres:
        condition: service_healthy
    extra_hosts:
      - "host.docker.internal:host-gateway"
    restart: unless-stopped

  postgres:
    image: pgvector/pgvector:pg16
    environment:
      POSTGRES_DB: abook
      POSTGRES_USER: abook
      POSTGRES_PASSWORD: abook
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U abook -d abook"]
      interval: 5s
      timeout: 5s
      retries: 10
    restart: unless-stopped

volumes:
  postgres_data:

Configuration

Environment Variables

Variable Default Description
ConnectionStrings__DefaultConnection PostgreSQL connection string
ASPNETCORE_ENVIRONMENT Development Production disables Swagger
LlmDefaults__Provider Ollama Default LLM provider (Ollama, OpenAI, GoogleAIStudio)
LlmDefaults__ModelName llama3 Default model name
LlmDefaults__Endpoint http://host.docker.internal:11434 Default LLM endpoint
LlmDefaults__ApiKey API key (required for OpenAI / GoogleAIStudio; optional for Ollama)
LlmDefaults__EmbeddingModelName Embedding model for RAG (optional; falls back to chat model)
AgentSettings__MaxConcurrentRuns 3 Max simultaneous agent runs across all books/users
PublicMode false Enable public library (anonymous access to published books)

Changing AgentSettings__MaxConcurrentRuns requires restarting the API process/container.

For local development, copy src/ABook.Api/appsettings.Local.example.jsonappsettings.Local.json and fill in your values.

LLM Providers

Configure the LLM backend in Settings or via the API:

Provider Notes
Ollama Default. Runs locally; host.docker.internal resolves to the host from inside Docker.
OpenAI Provide an API key and model name (e.g. gpt-4o). Leave endpoint blank for the real OpenAI API; set a custom endpoint for any OpenAI-compatible API (Groq, Together, LM Studio at http://host.docker.internal:1234/v1, etc.).
Google AI Studio Native Gemini connector. Requires an API key from aistudio.google.com. Suggested models: gemini-2.0-flash, gemini-2.5-pro. Embedding model: text-embedding-004.

Configurations can be set globally, per-user, or per-book. The lookup order is: book-specific → user-default → global.

MCP Access

ABook includes a built-in Model Context Protocol server at /mcp. Any MCP-compatible client can connect to read and write book content and trigger agent workflows.

Setup:

  1. Open SettingsMCP Access
  2. Generate an API token (or click Regenerate to rotate)
  3. Add the server to your MCP client config using Authorization: Bearer <token>

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "abook": {
      "type": "http",
      "url": "http://localhost:5000/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

VS Code / GitHub Copilot (.vscode/mcp.json):

{
  "servers": {
    "abook": {
      "type": "http",
      "url": "http://localhost:5000/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

Agent Workflow

User creates book (title, premise, genre, target chapters)
         │
         ├─ optional: choose a base book (settings + context copied)
         │
         ▼
  ┌──────────────────────────────────────────────────────┐
  │  Planner — 4-phase pipeline                          │
  │   Phase 1: Story Bible (world-building, tone, rules) │
  │   Phase 2: Character Cards (roles, arcs, goals)      │
  │   Phase 3: Plot Threads (subplots, themes, arcs)     │
  │   Phase 4: Chapter Outlines (title + synopsis each)  │
  │                                                      │
  │   Asks clarifying questions up front; optionally     │
  │   pauses after each phase in Human-assisted mode     │
  └──────────────────────────────────────────────────────┘
         │
         │  ← "Plan Only" stops here so you can review
         │    and edit outlines before clicking "Continue"
         ▼
  For each chapter:
  [Checker]  ── pre-write: checks outline for contradictions
         │
         ▼
  [Writer]  ── writes full chapter prose
         │
         ▼
  [Checker]  ── continuity + style review → structured JSON patches
         │
         ▼
  [Editor]  ── applies patches mechanically (skipped if no issues)
         │
         │  ← optional human pause in assisted mode: read the patched
         │    chapter, edit anything, and steer the rewrite
         ▼
  [Editor]  ── creative rewrite — only when the Checker asked for one
         │      or you gave instructions during the pause
         ▼
      Done ✓

Agents stream tokens via SignalR as they write.

Workflow controls:

Button Behaviour
Plan Only Runs the Planner and stops so you can review outlines
Write Book Full pipeline from scratch (idempotent — skips completed phases and Done chapters)
Continue Resumes from the first non-Done chapter
Continue Planning Re-runs only the incomplete planning phases
Stop Cancels any running agent cleanly

In Human-assisted mode the app also pauses after each planning phase, and once per chapter — after the Editor's mechanical fixes are applied but before the creative rewrite. While it is paused nothing is generating, so you are free to edit the chapter (title, outline and prose), the characters, the plot threads or the story bible; the next step re-reads all of it. Whatever you type in the answer box is passed to the rewrite as author instructions, and the rewrite is skipped altogether when the Checker found nothing to rewrite and you left the box empty.

Chapter edits you make by hand are re-embedded in the background, so retrieval for later chapters sees your text rather than the version the agent wrote.

For books created from a base book, chapter-level RAG retrieval includes embeddings from all ancestor books in the continuation chain.


Development

Prerequisites

Local Setup

# Start PostgreSQL
docker-compose up postgres -d

# Start the UI dev server (proxies API calls to localhost:5000)
cd src/abook-ui
npm install
npm run dev

# Start the API (second terminal)
cd src/ABook.Api
dotnet run --urls http://localhost:5000

The React dev server runs at http://localhost:5173 and proxies /api and /hubs to the ASP.NET server.

Database Migrations

dotnet ef migrations add <MigrationName> --project src/ABook.Infrastructure --startup-project src/ABook.Api
dotnet ef database update --project src/ABook.Infrastructure --startup-project src/ABook.Api

Always use the dotnet ef CLI — never create migration files by hand.

Build Docker Image

docker build -t abook .

The multi-stage Dockerfile builds the React app (Node 20), compiles the .NET API (.NET 10 SDK), and produces a minimal runtime image (ASP.NET 10).

LLM Debug Logging

Set LLM_DEBUG_LOGGING=true to print the full chat history and LLM responses to the application log at Information level.


Tech Stack

Layer Technology
Frontend React 19, TypeScript, Vite, Zustand, react-markdown
Backend ASP.NET Core 10, C#
LLM Ollama, OpenAI SDK, Google AI SDK (per-provider direct calls)
Database PostgreSQL 16 via EF Core 10 + Npgsql
Vector store pgvector (in-DB, Pgvector.EntityFrameworkCore)
Real-time SignalR
Auth Cookie-based, IPasswordHasher<T>, Bearer API token for MCP
MCP ModelContextProtocol.AspNetCore 1.2.0 — HTTP/SSE transport, 37 tools
Container Docker, Docker Compose

License

MIT

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages