Lorekeep
A file-sovereign, temporal knowledge graph shared by you and your coding agents over MCP.
Lorekeep compiles Markdown from multiple namespaces into a deterministic
facts.jsonl graph, projects that graph into a human-readable Obsidian/Tolaria
wiki, and exposes a compact namespace-scoped MCP surface to Claude Code, Cursor,
Codex, and opencode. Agents can also propose facts during a session; proposals
land in append-only journals and become visible after a confidence-gated resolve.
The LLM work happens during compile or an explicitly requested deep import. Ordinary graph queries, journal writes, resolve, wiki generation, lint, and status checks do not call another LLM.
What is available today
| Area | Current behavior |
|---|---|
| Compile | raw/<ns>/*.md → schema-constrained extraction → resolve → sorted facts.jsonl + manifest + wiki |
| Query | Seven MCP tools plus passive schema, namespace, and status resources |
| Permission | Deny-by-default namespace filtering through one ScopedGraph chokepoint |
| Time | Half-open validity windows plus snapshot, history, and change queries |
| Agent input | Session import and hooks for Claude Code, Cursor, Codex, and opencode |
| Agent writes | Namespace-enforced, confidence-gated journals; no direct graph mutation |
| Automation | Watch raw docs, journals, memories/transcripts, agent wiring, backup sync, and restart after an external package upgrade |
| Human view | Deterministic, readable Markdown wiki for Obsidian and Tolaria |
| Operations | Runtime logs, redacted support bundles, install diagnostics, and optional automatic GitHub issues |
Lorekeep is suitable for one person using several coding agents and several devices, with an important current constraint: Git backup/sync is sequential. Simultaneous edits to the same raw document or journal can still require manual conflict resolution. A shared authenticated team server is roadmap work, not a shipped capability.
Install
Python 3.11+ and uv are required.
# Run without a permanent install
uvx lorekeep version
# Recommended when using the daemon/service continuously
uv tool install lorekeep
lorekeep version
For development from source:
git clone https://github.com/manhhailua/lorekeep.git
cd lorekeep
uv sync
uv run lorekeep version
Quickstart
# 1. Interactive setup: config + schema + profile + agent wiring + initial import
lorekeep init
# 2. Add Markdown under the raw directory printed by init
mkdir -p ~/.local/share/lorekeep/raw/backend
cp your-docs.md ~/.local/share/lorekeep/raw/backend/
# 3. Compile raw docs, merge journals, and regenerate the wiki
lorekeep compile
# 4. Inspect installed/active/wired coding agents
lorekeep agent detect
# 5. Validate graph, schema, MCP, and provider connectivity
lorekeep doctor
init is idempotent. On its first interactive run it selects a provider and
namespace, writes about.md + profile.md, detects installed coding agents,
writes their MCP configuration and supported session-end hooks, quick-imports
available memory files, compiles when a usable provider key exists, and starts a
background watcher unless --no-watch is passed.
If an agent was not detected, wire it explicitly:
lorekeep mcp add --agent codex --scope user --ns backend
# or use the registry-aware command:
lorekeep agent wire --agent codex --scope user --ns backend
Restart the coding agent after its MCP configuration changes. Open the generated
wiki with lorekeep wiki --open, or select the printed wiki/ directory in
Obsidian/Tolaria.
For non-interactive setup, use lorekeep init --yes --no-watch; add a provider
key and run lorekeep compile afterwards.
Runtime model
COMPILE / CURATE
raw/<ns>/*.md ──> chunk ──> extract(LLM, cached) ──> resolve ──┐
│
pending/<ns>/journal.jsonl ──> confidence gate + replay ────────┤
v
facts.jsonl + manifest.json
│
├──> wiki/*.md
└──> local FTS cache
SERVE / USE
facts.jsonl ──> GraphStore ──> ScopedGraph(allowed namespaces) ──> MCP
^ lazy reload on facts.jsonl mtime │
└──────────── resolve <──── namespace journal <──── agent write ─┘
Raw Markdown, schema.json, and accepted/pending journals are the durable
knowledge inputs. The graph, manifest, wiki, cache, and FTS index are derived and
can be rebuilt on each device.
Compile, resolve, and wiki
lorekeep compile is the normal all-in-one operation:
- chunk
raw/withpath:lineprovenance; - extract typed nodes, edges, aliases, summaries, and relation descriptions;
- resolve aliases, validate facts, and quarantine invalid candidates;
- write sorted
facts.jsonlandmanifest.jsonatomically; - replay/merge journals when present; and
- generate the wiki once from the final graph.
Unchanged chunks use a hash cache, so they do not repeat extraction calls; sorted publication keeps the resulting graph byte-stable for unchanged inputs.
Use the narrower commands when only the derived view or journals changed:
lorekeep resolve # merge pending journal entries; zero LLM calls
lorekeep wiki --open # re-project the existing graph; zero LLM calls
Daemon and service
lorekeep agent watch polls at a configurable interval (60 seconds by default)
and currently performs event-driven maintenance:
- raw file count/mtime or schema change → compile;
- journal mtime change → resolve;
- Claude/Codex memory change → quick import;
- supported live transcripts → bounded Markdown dumps under
raw/; - detected agent change → idempotent MCP/hook wiring;
- successful compile → self-heal, wiki refresh, and backup sync when configured;
- installed Lorekeep version change → restart the running watcher.
It does not currently run nightly lint, weekly suggestions, or an autonomous schema-evolution scheduler. Run those one-shot operations explicitly:
lorekeep agent lint
lorekeep agent lint --auto-fix
lorekeep agent suggest
lorekeep agent status
For login/restart persistence:
lorekeep agent service install
lorekeep agent service status
MCP contract
The runtime exposes exactly seven composable tools:
| Tool | Purpose |
|---|---|
search(query, limit=10) |
Find visible nodes by id, type, and properties |
get_node(id) |
Fetch one visible node with properties and provenance |
neighbors(id, edge_type="", depth=1) |
Traverse visible edges in both directions, up to five hops |
temporal_query(mode, params) |
at_time, history, or changes |
context(section="all", topic="") |
Ontology, visible namespaces, coverage, freshness, and pending count |
propose_change(operation, payload, confidence) |
Journal a create, link, or complete-props update |
review_note(kind, description, fact_ids=None) |
Record a contradiction or improvement for curator review |
Clients that support MCP resources can also read:
lorekeep://schemalorekeep://namespaceslorekeep://status
Every graph-fact query and graph statistic goes through ScopedGraph. Effective
visibility is the configured scope plus public; an edge is returned only when
its own namespace and both endpoints are visible. Static schema and aggregate
compile/pending operational metadata are process-wide. Write namespaces come
from the verified server scope, not from caller payloads.
Making the MCP server available does not guarantee that every coding agent will
choose to call it. init and mcp add print an instruction snippet that tells
the agent to use this retrieval sequence:
context(section="status") → search(query) → get_node(id) → neighbors/temporal_query
Keep that snippet in the agent's project/user instructions when the client does
not persist it automatically. Agents should cite src, check graph freshness,
and treat “not found” as “absent or outside this namespace,” not proof that a
fact does not exist globally.
Configuration
All model names must use LiteLLM's {provider}/{model} form. Native providers
include OpenAI, Anthropic, DeepSeek, DashScope/Qwen, Gemini, OpenRouter, Mistral,
Groq, Together AI, and others exposed by LiteLLM. Ollama, vLLM, and LM Studio are
available for local/custom endpoints.
provider:
model: deepseek/deepseek-chat
api_key_env: DEEPSEEK_API_KEY
timeout_seconds: 120
max_retries: 2
ns:
default: [me]
personal: me
agents:
enabled: [claude, codex, cursor, opencode]
auto_wire: true
wire_scope: user
watch_transcripts: true
self_heal: true
Prefer provider.api_key_env. An inline provider.api_key is accepted only in
the local gitignored config.yaml. Native providers normally need no
api_base; set it for Ollama on a non-default host or another custom
OpenAI-compatible endpoint. See the validated
configuration example.
Change settings without editing YAML:
lorekeep config show
lorekeep config set provider.model openrouter/deepseek/deepseek-chat
lorekeep config set provider.api_key_env OPENROUTER_API_KEY
lorekeep config set ns.default me,backend
lorekeep config set agents.wire_scope user
Optional LiteLLM tracing is available through Langfuse or LangSmith by setting
observability.provider and the corresponding environment credentials.
Data home and paths
Path precedence, high to low:
- per-path
LOREKEEP_RAW,LOREKEEP_OUT,LOREKEEP_CACHE,LOREKEEP_SCHEMA,LOREKEEP_CONFIG,LOREKEEP_PENDING,LOREKEEP_WIKI, orLOREKEEP_LOGS; LOREKEEP_HOME;- development mode (
.lorekeep/in the current checkout orLOREKEEP_DEV=1); and - platform XDG/application directories.
Installed Linux defaults place config at ~/.config/lorekeep/config.yaml and
data at ~/.local/share/lorekeep/. See the
data-home guide for other platforms and overrides.
Backup and multi-device use
Initialize a separate private Git remote for the resolved data home:
lorekeep backup --init https://github.com/<you>/lorekeep-data.git
lorekeep backup
The generated backup ignore rules exclude local configuration/secrets and
derived graph, manifest, wiki, cache, FTS, and lock files. Raw docs,
schema.json, and pending/ journals are durable inputs and are committed.
Journals can contain sensitive context, including quarantined proposals, so the
remote must remain private.
The watcher fetches/rebases at startup and synchronizes after a successful
compile. Manual lorekeep backup pushes the current branch; if two devices
changed the same tracked content, resolve the ordinary Git rebase conflict and
retry. Lorekeep does not yet provide conflict-free simultaneous editing or a
central reconciler.
Diagnostics and support
lorekeep doctor is the pass/fail installation check. Runtime logs live under
the resolved logs/ directory and avoid prompts, raw docs, fact properties,
journal payloads, and credentials.
lorekeep doctor
lorekeep agent service status
lorekeep support # print report + create redacted ZIP
lorekeep support --report-only
lorekeep support status # automatic issue-reporting state
lorekeep support off # disable automatic issue creation
The support bundle contains an allowlisted report, redacted log tail, and manifest counters—not raw knowledge or configuration. See runtime logging and bug reports.
Current limits
- Search is keyword/FTS plus graph traversal; hybrid/vector retrieval is planned.
- Git sync is sequential; conflicting simultaneous edits need manual resolution.
- Local stdio is the supported transport; authenticated shared-team HTTP hosting and OIDC/SSO are not shipped.
- Lint, suggest, and contribution analysis are one-shot commands, not scheduled jobs.
- There are no built-in software-source connectors for repositories, observability systems, CI, Confluence, PDFs, or URLs yet.
- Coding-agent tool use depends on the client's MCP support and instructions.
See the roadmap for unshipped directions. Architecture docs describe only current behavior unless a section is explicitly marked planned.
Development
uv sync
uv run pytest
uv run pytest tests/test_core_regression.py -q
uv run python scripts/generate_cli_reference.py --check
uv build
Tests use FakeProvider; no API key or network call is required. Determinism and
the compact seven-tool MCP surface are regression contracts.
Documentation
Start at the documentation index.
- Getting started
- Compiling and resolving
- Importing agent sessions
- Serving the graph over MCP
- Browsing the wiki
- Backing up and syncing
- Runtime logging and bug reports
- Architecture overview
- Generated CLI reference
License
Lorekeep is released under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lorekeep-0.25.0.tar.gz.
File metadata
- Download URL: lorekeep-0.25.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
370196ae36c1c2454a1cb48208ce5ba965f5819e0a5fbf822115987508f097d3
|
|
| MD5 |
2e6c15d6d218e221bd6436fa970f862b
|
|
| BLAKE2b-256 |
e975f45dcbffef87abf4f7ca916638c4f356cd4f6682cd5868fcb1fa4d7ee813
|
Provenance
The following attestation bundles were made for lorekeep-0.25.0.tar.gz:
Publisher:
release-please.yml on manhhailua/lorekeep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lorekeep-0.25.0.tar.gz -
Subject digest:
370196ae36c1c2454a1cb48208ce5ba965f5819e0a5fbf822115987508f097d3 - Sigstore transparency entry: 2388840183
- Sigstore integration time:
-
Permalink:
manhhailua/lorekeep@c20827d115bd49071213b0c88233a494318fd4ee -
Branch / Tag:
refs/heads/main - Owner: https://github.com/manhhailua
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-please.yml@c20827d115bd49071213b0c88233a494318fd4ee -
Trigger Event:
push
-
Statement type:
File details
Details for the file lorekeep-0.25.0-py3-none-any.whl.
File metadata
- Download URL: lorekeep-0.25.0-py3-none-any.whl
- Upload date:
- Size: 149.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1fe6c62d6a9059d7319fde6e94e8ffd56ec17e65580da7482552d65561a4e60
|
|
| MD5 |
18f6fda60ec29c524f7d60de42fb7291
|
|
| BLAKE2b-256 |
fbb75c4a05b34c36beec6154fc0444c9d65f14e1c0d1419443189741355d6563
|
Provenance
The following attestation bundles were made for lorekeep-0.25.0-py3-none-any.whl:
Publisher:
release-please.yml on manhhailua/lorekeep
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lorekeep-0.25.0-py3-none-any.whl -
Subject digest:
c1fe6c62d6a9059d7319fde6e94e8ffd56ec17e65580da7482552d65561a4e60 - Sigstore transparency entry: 2388840216
- Sigstore integration time:
-
Permalink:
manhhailua/lorekeep@c20827d115bd49071213b0c88233a494318fd4ee -
Branch / Tag:
refs/heads/main - Owner: https://github.com/manhhailua
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-please.yml@c20827d115bd49071213b0c88233a494318fd4ee -
Trigger Event:
push
-
Statement type: