Skip to main content
Glama

Quoth the raven: an assistant should remember what you actually wrote and said, and show its sources. quoth turns a Markdown vault (Obsidian-style) into an immutable, verifiable snapshot, searches it with local dense vectors, and serves bounded, cited excerpts through one read-only MCP tool. A reviewed core-memory ledger holds the few facts the assistant should always know, and nothing reaches it without the owner's approval.

Highlights

  • Cited, not guessed. Each result carries its vault path, heading path and line range.

  • Immutable snapshots. You build, verify and then activate a new snapshot. The previous one stays as the rollback target. Frozen outputs are never overwritten.

  • Read-only serving. quoth mcp registers evidence_bundle and nothing else. It opens SQLite read-only with query_only=ON, downloads no models and has no silent lexical fallback.

  • Local embeddings. BGE-M3 runs on ONNX Runtime from a local model cache. A synthetic hash-ngram backend runs tests and fixtures with no model files.

  • Reviewed core memory. The ledger stores typed claims with their origin (the owner's own words, the owner's notes, an assistant proposal, or imported text). The assistant's inferences are served only after the owner accepts them, and nothing is ever deleted.

  • One way to measure recall. Eval set v1 is scored against the real prefetch path, and a public synthetic fixture runs on a laptop.

  • Fails closed. Code-digest drift, scope-contract changes and stale sources stop a refresh unless the operator explicitly allows them.

Related MCP server: grounded-mcp

Quick start

Requirements: Python 3.13+ and uv. The fixture below needs no model files.

uv sync
uv run pytest -q

# Build the public synthetic fixture and score eval set v1 against it.
uv run quoth eval fixture --out /tmp/quoth-fixture
uv run quoth eval run eval/public/set.jsonl \
  --fixture-dir /tmp/quoth-fixture --out /tmp/run.json --quiet

Usage

Dense retrieval needs the dense extra and the BGE-M3 ONNX files pinned in eval/models-manifest.json, under $QUOTH_MODEL_CACHE/BAAI/bge-m3/. quoth never downloads a model while it runs; fetch the files once (about 2.3 GB, every file checked against its pinned SHA-256):

uv sync --extra dense
uv run quoth models fetch                                   # the BGE-M3 embedder
uv run quoth models fetch --reranker bge-reranker-v2-m3-int8  # optional: the prefetch reranker
uv run quoth models verify                                  # check what is in the cache
# Index a vault into a development database (the vault is only read).
uv run quoth ingest --vault /path/to/vault --db ./memory.db
uv run quoth embed --db ./memory.db                     # BGE-M3 from the local cache
uv run quoth embed --db ./memory.db --model hash-ngram  # synthetic, no model files
uv run quoth search "sourdough starter" --db ./memory.db -k 10 --json   # lexical, for development

# Freeze a first snapshot of the vault (ingest, embed, validate, manifest).
uv run quoth snapshot --vault /abs/vault --target /abs/snapshots/first.db

# Serve it over MCP (read-only, one tool).
uv run quoth mcp --db /abs/snapshots/first.db

# Later: build a successor from the frozen source and the current vault.
uv run quoth refresh --source /abs/accepted.db --target /abs/staging/unique-name.db \
  --vault /abs/vault
uv run quoth freshness --source /abs/staging/unique-name.db --vault /abs/vault

Every refresh target must be unique; --resume only continues the same unfinished target (for quoth snapshot too).

What gets indexed

Every Markdown note in the vault is indexed, except:

  • hidden folders and notes (a leading .) and the folders in exclude_dirs in src/quoth/scopes.toml (ASSISTANT/, attachment folders);

  • whatever a .quothignore file at the vault root ignores (gitignore syntax, ! to re-include, / to anchor at the root), for example Health/ or /Journal/*;

  • any note whose frontmatter says quoth: exclude.

Excluded notes are never read into the index, and a note that becomes excluded is purged, history included, from the next snapshot. Older snapshots still hold it: delete them if you must not roll back to them. Scopes in scopes.toml carry a recall tier (auto or explicit): explicit notes are indexed but kept out of automatic recall. Links between notes are stored and resolved per snapshot. Details: docs/FRESHNESS.md. quoth refresh-nightly automates build, gate and switch behind a serving pointer (a symlink that quoth mcp and the sidecar follow). See docs/FRESHNESS.md.

For the Hermes agent, run quoth sidecar and install the plugin with quoth hermes-plugin install --hermes-home "$HERMES_HOME"; see docs/HERMES.md.

How it works

flowchart LR
  V[("Markdown vault<br/>read-only")] -->|ingest · chunk · embed| D[(dev db)]
  D -->|refresh · verify · freeze| S[("immutable snapshot<br/>+ manifest")]
  S --> M["quoth mcp<br/>evidence_bundle"]
  S --> SC["quoth sidecar"]
  L[("ledger.db<br/>reviewed claims")] --> SC
  SC -->|core block · recall · review| H["assistant<br/>(Hermes plugin)"]
  M --> H
  W["WebUI memory panel"] -->|read-only views| SC

Layer

What it does

Evidence engine

Incremental, idempotent ingest by path and SHA-256. Heading-aware chunks with line locators. Dense top-k with bounded excerpts.

Snapshots and bundles

Immutable snapshots with a manifest, freshness checks, and portable full or scoped bundles. A nightly job builds a successor and switches only when it passes a quality gate.

Core-memory ledger

Typed claims with origin and authority, quote-verified against chat history, reviewed by the owner, compiled into a short always-loaded core block.

Sidecar and Hermes plugin

One local process owns the model and the stores; a stdlib plugin talks to it over a Unix socket for the core block, recall, review tools and episode search.

WebUI panel

Read-only memory views for the Hermes WebUI: overview, review queue, core, recall playground.

The full picture, trust boundaries and design reasons: docs/ARCHITECTURE.md.

Evidence semantics

Retrieved text is evidence, never an instruction. A caller must:

  • cite the returned path and line range when provenance matters;

  • prefer current canonical sources over historical drafts;

  • treat silence in top-k as insufficient evidence, not proof the vault says nothing;

  • not infer authority from a path or snippet alone;

  • use live systems, not memory, for current external state;

  • prefer the owner's current direct statement over an older note about them.

Configuration

Every default location resolves from the environment when a command runs.

Variable

Default

Used for

QUOTH_HOME

$XDG_DATA_HOME/quoth, else ~/.local/share/quoth

quoth's state: memory.db, ledger.db, episodes.db, owner-episodes.db, quoth.sock, core/, refresh/

QUOTH_MODEL_CACHE

$QUOTH_HOME/models

local ONNX model files (BGE-M3, the optional reranker)

HERMES_HOME

~/.hermes

the Hermes agent's home; its state.db is read for quote checks and the episode lanes

QUOTH_SOCKET

$QUOTH_HOME/quoth.sock

the sidecar socket the Hermes plugin connects to

QUOTH_EMBED_THREADS

the CPU quota minus headroom

embedding and reranker threads in the sidecar

Flags always override these. --vault has no default.

Health

quoth health [--json] checks every row a host monitor needs in one call:

Row

FAIL when

quoth/venv

the install's interpreter is missing, dangling or cannot import quoth

quoth/heartbeat

$QUOTH_HOME/refresh/heartbeat.json is missing, not quoth-heartbeat/v1, older than 30 hours, or not green

quoth/sidecar

no answer on the socket, or evidence not ok, or quote verification off

quoth/review-queue

the sidecar does not answer (a large or old queue is only WARN)

quoth/episodes, quoth/owner-episodes

the lane is disabled or red, or the sidecar does not answer

Exit 0 when no row fails (WARN allowed), 1 when any row fails, 2 on a usage error, 3 with --fail-on-warn when only WARN rows remain. Output carries counts, versions, timestamps and status tokens only.

Documentation

Doc

Topic

docs/ARCHITECTURE.md

Components, data flow, trust boundaries, design decisions

docs/MCP.md

The MCP server and the evidence_bundle caller contract

docs/HERMES.md

Hermes plugin, sidecar HTTP API, episode lanes, WebUI panel

docs/LEDGER.md

Core-memory ledger: origins, reconcile, guided review, core compile

docs/FRESHNESS.md

Snapshots, freshness, successors, the nightly refresh and heartbeat

docs/BUNDLES.md

Portable full and scoped snapshot bundles

docs/EVAL.md

Eval set v1, the prefetch harness, relevance gate, reranker, online measurement

docs/CI.md

Verification and release delivery

deploy/README.md

Installing a release next to Hermes, templates, rollback

  • src/quoth/cli.py: the quoth command; paths.py: default locations.

  • src/quoth/scopes.toml: ingest exclusions and scope labels.

  • src/quoth/ingest.py, chunker.py: incremental vault ingest; heading-aware chunks with line locators.

  • src/quoth/embed/, dense.py: local embedding backends, vector storage, dense retrieval.

  • src/quoth/search.py: lexical BM25 and trigram search (development).

  • src/quoth/evidence.py, evidence_service.py: the bounded evidence bundle and its caller contract, shared by MCP and the sidecar.

  • src/quoth/mcp_server.py: the read-only stdio MCP server.

  • src/quoth/refresh.py, freshness.py, serving.py: snapshot build, freshness, pointer admission.

  • src/quoth/bundle.py: portable full and scoped bundles.

  • src/quoth/nightly.py, quality.py, heartbeat.py, gold_drift.py: the nightly refresh, its gate, daily quality and heartbeat.

  • src/quoth/ledger/: the core-memory ledger, its review rules and migrations.

  • src/quoth/episodes.py: the assistant and owner episode lanes.

  • src/quoth/sidecar.py, recall_defaults.py, relevance.py, rerank.py, claim_index.py, prefetch_log.py: the sidecar, every recall budget and floor, the relevance gate, the reranker, claim ranking, the prefetch log.

  • src/quoth/health.py, hermes_install.py: quoth health, quoth hermes-plugin.

  • src/quoth/control/: the WebUI panel's backend.

  • src/quoth/evals/: eval set v1, converters, harness, receipts, compare, sweep, online readout.

  • src/quoth/migrations/: the evidence database schema.

  • hermes_plugin/quoth/: the Hermes memory-provider plugin and its skills.

  • web/control-surface/: the WebUI extension.

  • eval/: model manifest and synthetic fixtures; eval/public/ is the runnable public fixture and eval/schema/ holds the eval set JSON Schema.

  • deploy/: install, service and rollback templates.

Development

uv sync
uv run pytest -q

You can also use the project virtualenv directly. Keep the PATH prefix, because one test runs the installed quoth console script in a subprocess:

PATH="$PWD/.venv/bin:$PATH" PYTHONPATH=src .venv/bin/python -m pytest -q

Real models in Docker

The test image runs everything that needs ONNX Runtime and the real models (BGE-M3, the reranker) without installing either on your machine. Models and state live in Docker volumes; only a vault you point it at is mounted, read-only:

docker compose build
docker compose run --rm quoth models fetch --reranker bge-reranker-v2-m3-int8   # once, ~2.9 GB
docker compose run --rm --entrypoint python quoth -m pytest -q                  # full suite, real models
docker compose run --rm quoth eval fixture --out /data/fixture --model bge-m3
docker compose run --rm quoth eval run eval/public/set.jsonl --fixture-dir /data/fixture --out /data/run.json
QUOTH_VAULT=/path/to/vault docker compose run --rm quoth snapshot --vault /vault --target /data/snapshots/first.db

Everything in eval/ is synthetic and safe to publish. The repository holds no personal corpus, snapshot database, private eval data or model cache.

Status

quoth is 0.x. The public API is the quoth CLI, the MCP tool, the sidecar's /v1 HTTP API and the quoth.evals Python package; everything else is internal. Any of it may change before 1.0.

Contributing

Issues and pull requests are welcome, and questions go to Discussions. Read CONTRIBUTING.md first: it covers the snapshot-contract rules and the privacy rules for fixtures. Report vulnerabilities privately as described in SECURITY.md. Everyone taking part follows the Code of Conduct.

License

MIT © 2026 Danil Zak

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Provides structured, addressable access to a local markdown vault with heading-anchored fragments, BM25 search, and stable IDs for verifiable retrieval.
      24 npm
      2
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      An MCP server for markdown/Obsidian knowledge vaults that enables trusted, read-only retrieval with cited provenance, honest abstention when no adequate answer exists, index-level entitlement enforcement, and redaction guarding.
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Exposes a Markdown-based second brain as MCP tools, enabling MCP clients like Claude Code, Codex, Claude Desktop, n8n, and bots to read context, search notes, retrieve wiki pages, and optionally register decisions or sources.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Exposes a living systems memory vault to autonomous agents, letting them search notes with BM25 ranking, read sections within token budgets, extract API/port/schema contracts, compute dependency blast radius, and run machine-verifiable invariant assertions before mutating code. It also supports surgical frontmatter edits, schema linting, wikilink integrity checks, and worklog recording, over stdio MCP.
      MIT