Setup Walkthrough

Step-by-step install. Scroll through and the next screen lights up. Stop whenever you want — each step is self-contained.

Est. time < 5 min // Skill floor Copy-paste + click

Pick your OS — the steps below adjust automatically.

Step 01

Download the zip

Grab chronicledb-v0.2.3.zip from the v0.2.3 release. The zip is self-contained — no git, no Node toolchain, no shell scripts. node_modules is bundled; the internal folder layout mirrors SillyTavern's so files land where ST expects them when you extract in Step 02.

Download chronicledb-v0.2.3.zip

Or browse all assets on the latest release page. The asset name follows the pattern chronicledb-vX.Y.Z.zip — the download button above is hardcoded to the current release and gets bumped each tag.

What's inside the zip (you don't rearrange anything — the folders mirror ST's layout so it extracts into the right places):
  • plugins/chronicle-db/ — server plugin with bundled node_modules (incl. @electric-sql/pglite for the embedded DB)
  • public/scripts/extensions/third-party/chronicle-db/ — UI extension (the drawer you'll see in Step 04)
Windows note: save the zip somewhere you can find it again, e.g. Downloads. Don't double-click to "open" it — that opens the zip in-place inside Explorer's zip viewer, which is not the same as extracting. Step 02 has the right-click flow.

Prefer running your own Postgres and pulling updates via git pull? See the Advanced install section at the bottom — install.sh / install.ps1 are still supported there.

Step 02

Extract into SillyTavern & enable plugins

Extract the zip so its two folders land on top of your SillyTavern install, then flip one line in config.yaml. That's the whole install.

A. Extract the zip into your SillyTavern folder

Two options — pick whichever you're comfortable with.

Finder: double-click chronicledb-v0.2.3.zip in Downloads. That creates a chronicledb-v0.2.3/ folder alongside it. Open that folder; you'll see plugins/ and public/ inside. Drag both into your SillyTavern folder — macOS will ask to merge; choose Merge.

Terminal:

cd ~/SillyTavern
unzip -o ~/Downloads/chronicledb-v0.2.3.zip

-o overwrites any existing files without prompting, which is what you want when you're upgrading a previous install.

From a terminal inside your SillyTavern folder:

cd ~/SillyTavern
unzip -o ~/Downloads/chronicledb-v0.2.3.zip

-o overwrites in place so upgrades from a previous ChronicleDB install don't need to be uninstalled first.

No unzip? sudo apt install unzip on Debian/Ubuntu, or sudo dnf install unzip on Fedora.
  1. In File Explorer, open the folder where you saved the zip (e.g. Downloads).
  2. Right-click chronicledb-v0.2.3.zipExtract All...
  3. In the Extract dialog, change the destination to the root of your SillyTavern install — e.g. C:\Users\YOU\SillyTavern or wherever you run Start.bat from. Click Extract.
  4. Windows will prompt to merge the plugins and public folders with the existing ones — choose Replace the files in the destination.

PowerShell equivalent if you prefer a one-liner:

Expand-Archive -Path $HOME\Downloads\chronicledb-v0.2.3.zip -DestinationPath $HOME\SillyTavern -Force
No admin, no Developer Mode, no WSL. The zip install is plain file copy — it doesn't create symlinks, junctions, or any elevated filesystem object, so the previous PowerShell 5.1 / BOM / privilege grief is gone.
What should be on disk after this:
  • <ST>/plugins/chronicle-db/ — with a populated node_modules/ inside
  • <ST>/public/scripts/extensions/third-party/chronicle-db/

If those two paths exist, extraction worked. Nothing else in your ST folder should have changed.

B. Enable server plugins

SillyTavern only loads server plugins when one line is flipped in config.yaml at your ST install's root. Open it in any text editor:

# ...other settings above...
enableServerPlugins: true
# ...other settings below...

If the key is already there and set to true, you're done — save and skip to Step 03. If it's false or missing, set/add it, save, and move on.

Where is config.yaml? Same folder as Start.bat / start.sh — the root of your SillyTavern install, not inside data/. Create it from default/config.yaml if you've never edited it before.
This is the one manual config step. Unlike the old install.sh, the zip install doesn't patch config.yaml for you — it's a plain file copy. Miss this and ST silently ignores the plugin on boot (you'll notice in Step 03).
Step 03

Restart SillyTavern

Stop ST, start it again. The server plugin initializes on boot, so without a restart the new code doesn't get loaded. You should see these lines in your terminal:

Users will be able to log in.
Extensions loaded.
[ChronicleDB] Initializing server plugin...
[ChronicleDB] Mind map path: /path/to/chronicledb/src/ui
[ChronicleDB] Server plugin ready.
SillyTavern is listening on IPv4: 0.0.0.0:8000

If you don't see the three [ChronicleDB] lines, something stopped the plugin from loading. Check config.yaml in your SillyTavern root:

enableServerPlugins: true
basicAuthMode: true
If enableServerPlugins is missing or false, the plugin is being silently ignored. Re-check Step 02B — set it to true, save, and restart ST again. A SillyTavern update can also revert it during a config merge, so this is worth re-checking after any ST upgrade.
Step 04

Open the settings panel

Inside SillyTavern, click the Extensions icon in the top bar (the one that looks like a stack of blocks), then scroll through the extensions list until you find the ChronicleDB drawer. Click its header to expand.

Lorebook Importer
Stable Diffusion
ChronicleDB
Translation
Vector Storage

Once expanded, the top of the drawer shows your connection status:

Enable ChronicleDB
Status: Checking… embedded PGlite @ <ST>/plugins/chronicle-db/pgdata
On the zip install, status should go green on its own. The default backend is embedded PGlite, created at <ST>/plugins/chronicle-db/pgdata on first connect — no fields to fill in, no external DB to stand up. If you see Not connected or a Checking… that never resolves, head to Troubleshooting.
Running your own Postgres? Step 05 covers the database fields. Zip-install users on the default PGlite backend can skim or skip it.
Step 05

Database fields (optional — external Postgres only)

Skip this step if you're on the default zip install. Embedded PGlite doesn't need any fields — the DB is created automatically at <ST>/plugins/chronicle-db/pgdata on first connect, and your status pill should already be green. This step only matters if you deliberately flipped Storage backend to External Postgres (e.g. you're running your own Postgres server, or you're using a cloud DB like Neon / Supabase).

If you are on external Postgres, fill in where it lives and hit Connect & initialize:

External Postgres
localhost
5432
chronicledb
you
(blank for local)
auto-detected
Connect & initialize
Storage backend toggle: stays on Embedded — PGlite by default — nothing to fill in. Flip to External Postgres to reveal the connection fields below.
Local Postgres defaults (if you stood one up yourself via brew / apt): host localhost, port 5432, db chronicledb, user is your OS username, password is blank (Postgres uses local trust auth by default). The Advanced install section runs install.sh which sets this up end-to-end.
Cloud DB (Neon): host ep-xxx.region.aws.neon.tech, port 5432, db = whatever name appears after the last / in the connection string, user + password from the Neon Dashboard's Direct connection string (not the Pooler). Neon requires SSL — ChronicleDB enables it automatically when the host isn't localhost.
Cloud DB (Supabase): host db.xxxxxxxxxxxx.supabase.co, port 5432 (the direct connection, not the pooler on 6543), db postgres, user postgres, password = whatever you set when creating the project. The pooler on 6543 runs in transaction mode and breaks DDL + pgvector init. Full step-by-step for both Neon and Supabase is in the Advanced install section.
ST data root is only worth touching if your SillyTavern lives somewhere unusual and the plugin can't find characters/ and chats/ on its own. Leave blank otherwise.

When you click Connect & initialize, the plugin runs CREATE EXTENSION IF NOT EXISTS vector and pg_trgm, then builds the full schema (tables, indexes, constraints). On a cloud DB this is the moment you'll find out if your user has the CREATE EXTENSION privilege — Neon and Supabase both grant it by default.

Step 06

LLM + embedding config

Two model blocks. The memory model reads your chats and pulls structured memory out — a cheap, fast model is fine; you do NOT need a frontier model here. The embedding model converts text into 768-dim vectors for semantic search.

Gemini
https://generativelanguage.googleapis.com/v1beta
AIza…•••••••••••••
gemini-3.1-flash-lite-preview
Strongly recommended — both free:
  • Memory model: gemini-3.1-flash-lite-preview
  • Embedding model: gemini-embedding-2-preview (covered in the next block)

Both fall under the Gemini free tier — see the Gemini pricing page (the "Free Tier" column) for current rate limits. Get a key at aistudio.google.com/apikey — it takes ~30 seconds, no credit card.

Don't use frontier models for extraction. The prompt is structured and doesn't need deep reasoning. Save your budget for the actual roleplay model.
OpenAI-compatible endpoints (OpenRouter, LiteLLM, Ollama, LM Studio, vLLM): pick OpenAI-compatible as the API type, set the API URL to your endpoint's /v1 base, paste the key, set the model name exactly as your provider lists it.
Gemini
gemini-embedding-2-preview
768
(blank)
(blank = reuse memory key)
Dimension is fixed at 768. The schema's vector(768) columns are baked in. Pick a model that natively outputs 768 dims, or one that honors a dimensions parameter — Gemini's gemini-embedding-2-preview, OpenAI's text-embedding-3-small / 3-large, and Vertex's text-embedding-004 / 005 all qualify.
Blank API key on the embedding block is fine — the plugin reuses the memory model's key if both use the same provider. Only set it if you're splitting providers (e.g. Gemini for extraction, Voyage for embeddings).
Step 07

Memory type toggles

Four switches gate what the extractor writes to the DB. All on by default; turn off any you don't want. These only affect future extractions — existing memory stays put.

Relationships
Events & timeline
What each character knows
World state
ToggleWhat it capturesWhen to turn off
Relationships Directional sentiment + intensity between every pair of characters who interact, with a short description. Solo-character RPs with no inter-character dynamics.
Events & timeline What happened each batch, with significance, participants, verbatim source quote, and causal chains. Pure character-study chats with no plot.
What each character knows Per-character epistemic state — what they've witnessed, been told, or explicitly don't know. Omniscient narration where no one is meaningfully ignorant.
World state Key-value facts about the setting (weather, faction standings, item ownership) with validity windows. Dialogue-driven chats with minimal world detail.
Traits and plot threads aren't toggle-able — they're core to the memory block. If you want fewer traits surfacing, tune the extraction prompt's caps (tight by default) or prune via the mindmap.
Step 08

Behavior knobs

How memory gets built while you chat and how much of it lands in your prompt. Safe defaults; touch when you have a reason.

Auto-build memory on new chats
1
3000
5
30
KnobDefaultWhat it does
Auto-build memory on Every reply automatically updates memory. Turn off if you only want memory from chats you explicitly ingest.
Update every N replies 1 How often the extractor fires. 1 = every message; 3 = every third. Higher = fewer API calls, coarser event-granularity.
Memory budget (tokens) 3000 Max tokens in the injected memory block. Higher = more memory in context, fewer tokens for the actual story.
Keep last N raw 5 Padding window. The latest N messages stay in ST's native context and aren't ingested yet. Lets you swipe / edit without triggering cleanup.
Refresh arcs every N 30 Incremental Louvain rebuild of the story-arc hierarchy, fires every N new events. Title-reuse makes the per-fire LLM cost near zero. 0 disables — only manual full-chat ingest rebuilds arcs.
Cost-tuning: if extraction API cost is biting, the cheapest lever is bumping Update every N replies from 1 to 3 or 5. You lose some sub-scene event granularity but the memory block is nearly identical.
Step 09

Per-character memory

Each character has their own memory scope. Three modes plus a per-character chat picker that lets you opt specific past chats in or out. These settings are per-character, not global.

Persistent — remember across chats

Include chats
Chat from 2026-04-12 — The Glass Library
Chat from 2026-04-15 — Eden's bargain
Chat from 2026-04-18 — side story, draft
Select all Select none Build memory from all
ModeEffect
Persistent Character remembers across every checked chat. The inject pulls from all of them, scoped to this character's participations.
Isolated Fresh slate per chat. No cross-pollination. New extractions still write to the DB, but retrieval only surfaces this-chat data.
Read-only Reads existing memory but doesn't add new extractions. Useful when you want to test / read-through an archived story without polluting it.
Per-chat scoping is automatic for new characters extracted after mid-April 2026. Older global character rows (from before the scoping change) keep working and are still visible through the chat picker — they just aren't bleed-isolated.
Build memory from all reads every past chat for this character and batch-processes them through the extractor. Depending on chat length and API speed this can take several minutes and will spend API tokens proportional to chat length.
Step 10

You're done

That's it. Open a chat, send a message, watch the memory block fire in your terminal or in SillyTavern's chat completion log. Your next few messages will be light on memory (the DB is still bootstrapping); after 5-10 turns the inject becomes rich.

Extracting… — pulled 2 events, 1 trait, 3 relationships
Assembling… — 1,247 tokens / 3,000 budget
Indexing… — 3 new memory_embeddings

Where to go next

  • Click Open mind map in the drawer — it'll launch a 3D WebGL graph of every character, event, and plot thread this chat has accumulated.
  • Check Debug: recent LLM calls at the bottom of the drawer if something feels off. Every extraction and embedding call shows up with status, latency, and error.
  • To import an existing chat history: Character memoryBuild memory from all.
  • Questions or bugs: GitHub Issues.
← Back to overview
+ Advanced

Advanced install: Postgres & git-based updates

The zip install covers almost every case — don't use this section unless you have a specific reason. Pick the advanced path if:

  • You want a full local PostgreSQL 17 + pgvector rather than the embedded PGlite (larger datasets, concurrent access, want to poke at the DB with psql).
  • You want to follow the project's master branch via git pull instead of waiting for a tagged zip.
  • You want a cloud Postgres (Neon / Supabase) wired in from the start, with install.sh --skip-postgres handling everything except the DB itself.

Otherwise, stay on the zip install above — it's simpler and has fewer moving parts.

A. Clone the repo
Windows note: either PowerShell or Git Bash works — both have git once you install Git for Windows. Whether you need WSL depends on your database choice in step B — a cloud DB skips WSL entirely.

Two ways: git clone (recommended — easy to pull updates later) or download the repo ZIP (no git required). Either way you'll end up with the repo on disk, and step B will run the installer from there.

Open a terminal and run:

git clone https://github.com/alani-fan-club/chronicledb ~/.chronicledb
cd ~/.chronicledb
Why this location? ~/.chronicledb is the default the installer expects. Put it anywhere you like — just remember the path for step B.

Updating later: cd ~/.chronicledb && git pull, then re-run install.sh / install.ps1 and restart SillyTavern.

If you don't have git installed, grab a source ZIP from GitHub (this is not the release zip — it's the raw repo):

  1. Go to github.com/alani-fan-club/chronicledb
  2. Click the green Code button → Download ZIP
  3. Unzip it somewhere you'll remember — e.g. ~/.chronicledb:
unzip ~/Downloads/chronicledb-master.zip -d ~/
mv ~/chronicledb-master ~/.chronicledb
cd ~/.chronicledb

Updating later without git means repeating this download + unzip dance. Consider installing git first if you plan to stay on master.

B. Run the installer (local Postgres or cloud DB)

Two routes. If you want a local Postgres, run install.sh — it sets up everything in one shot (Postgres, symlinks into ST, config.yaml patch). If you'd rather use a free cloud DB, skip the local Postgres install and do the wiring manually.

Open PowerShell (regular, not Administrator) and run:

irm https://raw.githubusercontent.com/alani-fan-club/chronicledb/master/install.ps1 | iex

No WSL, no admin, no Postgres install — the embedded PGlite database lives entirely inside the plugin. The installer junctions the plugin and UI extension into your SillyTavern folder (junctions, unlike symlinks, don't need elevation or Developer Mode).

Prereqs: Node.js 18+ and Git for Windows. The installer checks for both and tells you what's missing.

From inside the ChronicleDB directory you cloned in step A:

bash install.sh

The script will prompt a few times. Answer yes to each to keep going. Here's what it does and what you'll see:

[chronicledb] Platform: macos
[chronicledb] Found SillyTavern at /Users/you/SillyTavern
[chronicledb] PostgreSQL is not installed.
[?] Install PostgreSQL 17 + pgvector via Homebrew now? [Y/n] y
[+] Running: brew install postgresql@17 pgvector
[+] Running: brew services start postgresql@17
[+] npm install in server-plugin ...
[+] Symlinking plugin into SillyTavern ...
[+] Symlinking UI extension ...
[+] Enabling enableServerPlugins in config.yaml ...
[+] Creating database 'chronicledb' ...
[+] Enabling extensions (vector, pg_trgm) ...
[ok] Install complete.
         Database: chronicledb @ localhost:5432 as $USER
         Plugin:   ~/SillyTavern/.../third-party/chronicle-db
Prereq: Homebrew (brew.sh). If you don't have it, the script will tell you to install it first.
[chronicledb] Platform: linux
[chronicledb] Found SillyTavern at /home/you/SillyTavern
[chronicledb] PostgreSQL is not installed.
[?] Install PostgreSQL 17 + pgvector via apt now? (will sudo) [Y/n] y
[+] Running: sudo apt-get install postgresql-17 postgresql-17-pgvector
[+] Running: sudo systemctl start postgresql
[+] Creating Postgres role for current user 'you' ...
[+] npm install in server-plugin ...
[+] Symlinking plugin into SillyTavern ...
[+] Symlinking UI extension ...
[+] Enabling enableServerPlugins in config.yaml ...
[+] Creating database 'chronicledb' ...
[+] Enabling extensions (vector, pg_trgm) ...
[ok] Install complete.
         Database: chronicledb @ localhost:5432 as you
         Plugin:   ~/SillyTavern/.../third-party/chronicle-db
Expect a sudo password prompt. The script sudos to install Postgres via apt and create your OS user's Postgres role.
Idempotent. If the script fails partway (network hiccup, permission prompt you missed), just re-run it. It detects what's already done and skips those steps.

Settings for Step 05: host localhost, port 5432, database chronicledb, user = your system username, no password.

Set up a free cloud Postgres first, then run install.sh with the --skip-postgres flag — it'll do the npm install, ST symlinks, and config.yaml patch without touching a local database.

B1. Create a cloud Postgres

Pick one. Both have free tiers and ship pgvector. Whichever you pick, you'll end up with a connection string of the form postgresql://USER:PASSWORD@HOST:PORT/DATABASE — map the five fields from that into the ST settings panel in Step 05.

Supabase — step by step
  1. Sign up at supabase.com and create a new project. Set a database password — save it somewhere, Supabase only shows it once.
  2. Wait for the project to provision (~1 min).
  3. Go to Database → Extensions. Toggle on both vector (pgvector) and pg_trgm. Without these the schema init fails at the CREATE EXTENSION lines.
  4. Open Project Settings → DatabaseConnection string. Copy the URI tab. It looks like:
    postgresql://postgres:[YOUR-PASSWORD]@db.xxxxxxxxxxxx.supabase.co:5432/postgres
  5. The five fields you'll paste into ST's Database panel:
    Hostdb.xxxxxxxxxxxx.supabase.co
    Port5432 (direct connection — not 6543, the pooler)
    Databasepostgres
    Userpostgres
    Passwordthe one you saved in step 1
Two Supabase quirks to know:
  • Use port 5432, not 6543. 6543 is the transaction pooler (PgBouncer); pgvector and the schema-init transactions ChronicleDB runs at startup don't behave under it. Direct on 5432 is what you want.
  • Free tier pauses after a week of inactivity. The first request after a pause hangs ~30s while the project wakes up. ChronicleDB's reconnect logic catches it but the status badge will flicker red briefly — that's normal.
Neon — step by step
  1. Sign up at neon.tech and create a project. Default database name is fine.
  2. Open the SQL Editor and run:
    CREATE EXTENSION vector;
    CREATE EXTENSION pg_trgm;
  3. From the project Dashboard, copy the Connection string (Direct, not Pooler):
    postgresql://USER:PASSWORD@ep-xxxxx.region.aws.neon.tech/dbname
  4. Map into ST's Database panel: host = ep-xxxxx.region.aws.neon.tech, port = 5432, database = whatever name you see after the last /, user + password = whatever's between :// and @.
Neon quirks: use the Direct connection string, not the pooler. Free-tier branches autosuspend after 5 min idle — the wakeup is faster than Supabase (a second or two) but the first query after idle still pays the cost.

B2. Wire the plugin into SillyTavern

From the directory you cloned in step A:

bash install.sh --skip-postgres

In a regular PowerShell window:

# Download once so we can pass the flag (iex doesn't forward args)
iwr https://raw.githubusercontent.com/alani-fan-club/chronicledb/master/install.ps1 -OutFile $env:TEMP\install.ps1
& $env:TEMP\install.ps1 -ExternalPostgres

Same installer as the local path, just with -ExternalPostgres so it skips the embedded PGlite default. Paste the cloud DB host/port/db/user/password into the ST settings panel after restart.

[chronicledb] Platform: macos
[chronicledb] Found SillyTavern at /Users/you/SillyTavern
[chronicledb] Node v20.11.0
[chronicledb] Skipping local PostgreSQL setup (--skip-postgres)
[chronicledb] Skipping pgvector check (--skip-postgres)
[+] npm install in server-plugin ...
[+] Symlinking plugin into SillyTavern ...
[+] Symlinking UI extension ...
[+] Enabling enableServerPlugins in config.yaml ...
[chronicledb] Skipping database creation (--skip-postgres).
[chronicledb]   Paste your cloud DB connection info into the ST
[chronicledb]   settings panel after restart.
[ok] Install complete.
Why a flag instead of detection? The script can't tell whether you want a local or cloud DB from the outside, so it asks explicitly. SKIP_POSTGRES=1 as an env var works too if you prefer.
Keep your connection string private. It includes credentials. If you share your settings export, strip the password first.

After either branch completes, come back to Step 03 and continue from the restart.

Common problems

Install gone sideways? Almost every report so far has been one of the issues below. Each one says what the symptom looks like, why it happens, and the exact fix.

Mind map character sidebar is empty (no character cards loading)

Symptom: The mind map opens, you see graph nodes for whatever extraction has produced, but the Characters sidebar on the right shows only "SHOW ALL" with nothing under it.

Cause: The plugin reads character cards from <ST data root>/characters/*.png. It auto-detects the data root from process.cwd(), which is wrong on Windows when SillyTavern is launched via a shortcut or batch file that doesn't cd into the ST install directory first — cwd ends up being something like C:\Windows\system32 instead of the ST root.

Fix: In the ChronicleDB settings panel, fill in the SillyTavern data root (optional) field with the absolute path to your data directory. Examples:

  • Standard install: C:\Users\YOU\SillyTavern\data\default-user
  • SillyTavern Launcher: C:\Users\YOU\SillyTavern-Launcher\SillyTavern\data\default-user
  • macOS / Linux: ~/SillyTavern/data/default-user

Save, refresh the mind map page, sidebar should populate.

SillyTavern crashes on startup with cannot find module 'express'

Symptom: ST refuses to start; the terminal log shows Error: Cannot find module 'express' with a stack trace pointing at the chronicle-db plugin.

Cause: Older release tarballs (v0.1.x) didn't list express in the server-plugin's package.json — it was relying on a top-level npm install at the repo root that you may have skipped if you cloned the plugin folder by hand.

Fix: Either pull the latest master (where express is now declared), or just install it directly into the plugin folder:

cd <wherever you cloned chronicledb>/server-plugin
npm install express

Then restart ST.

Status badge stays red — getaddrinfo ENOTFOUND in the log

Symptom: Status badge is red, and the ST terminal log shows getaddrinfo ENOTFOUND db.something.supabase.co (or similar) on each connect attempt.

Cause: The hostname in the Database panel doesn't resolve via DNS. The most common reasons: a typo, a leading/trailing space (yes, really), or you pasted the placeholder from the Supabase docs (db.[YOUR-REF].supabase.co) without substituting your actual project ref.

Fix: Open the Database section, double-check the host field. For Supabase, it should be db.<your-12-char-project-ref>.supabase.co — no [, ], or trailing whitespace. Save and the plugin retries automatically.

Status badge stays red — Supabase connects but schema init fails

Symptom: The plugin reaches Supabase but Connect & initialize errors out, often with a complaint about CREATE EXTENSION or DDL inside a transaction.

Cause: Two possibilities, both Supabase-specific.

  1. Wrong port. 6543 is the transaction pooler — pgvector + the schema-init transactions don't survive PgBouncer's transaction mode. Use 5432 (the direct connection) instead.
  2. Extensions not enabled. Supabase doesn't enable vector and pg_trgm by default. Open Database → Extensions in the Supabase dashboard and toggle both on.
PowerShell refuses to create the symlinks (Windows manual install)

Symptom: New-Item -ItemType SymbolicLink errors out with "A required privilege is not held by the client" or similar.

Fix: Don't use SymbolicLink — use a Junction instead. Junctions are NTFS reparse points for directories that don't require admin or Developer Mode:

New-Item -ItemType Junction `
  -Path $HOME\SillyTavern\plugins\chronicle-db `
  -Target <path-to-chronicledb>\server-plugin

Or just run install.ps1 — it uses junctions out of the box, no manual steps needed.

Mind map nodes are present but no memory ever appears in chat context

Symptom: Extraction is clearly happening (you can see characters and events in the mind map), but ST's chat completion log shows no [ChronicleDB Memory] block being injected.

First check: the Enable ChronicleDB toggle at the top of the settings panel is on. If yes, open Debug: recent LLM calls at the bottom and confirm the memory model is being called — if it's silent during a fresh reply, the inject hook isn't firing. Restart ST once; if still silent, file an issue with the contents of the debug table.

Same character appears as multiple nodes in the mind map

Symptom: "James Roe" and "Captain Roe" (or "Lyra" / "Lady Lyra" / "the merchant's daughter" etc.) show up as separate nodes even though they're the same person in your story.

Cause: Pre-master extractor only deduped on exact name match. Newer builds (post the alias-aware upsertCharacter fix) collapse surface variants automatically going forward, but pre-existing duplicates need a one-shot merge.

Fix: Pull master and run server-plugin/merge-characters.js from the repo root. Pass --canonical "Real Name" and --merge "Variant 1" "Variant 2" .... Add --dry-run first to preview. Stop ST first if you're on PGlite (single-writer lock).

Hit something not covered here? Open an issue at github.com/alani-fan-club/chronicledb/issues with the contents of the ST terminal log around the failure — that's almost always enough to diagnose.