lore-mcp
Enables shared, multi-agent persistent storage for the knowledge base, investigations, and journal using PostgreSQL, suitable for team and production environments.
Provides local persistent storage for the knowledge base, investigations, and journal using SQLite, requiring no external database setup.
Lore
lore-knowledge-mcp · Operational knowledge layer for engineering teams and their AI agents.

The Problem
Your agents start every session knowing nothing about your systems. Every runbook you've written. Every gotcha you've hit. Every incident you've debugged. None of it carries forward.
You re-explain. They re-discover. Context vanishes when the session ends.
Lore fixes that.
Without Lore With Lore
───────────────────────────── ──────────────────────────────────
Agent starts fresh every time Agent queries Lore on startup
"How does our infra work?" Gets: topology, gotchas, runbooks,
You re-explain everything past incidents, verified decisions
Context lost at session end Knowledge persists across all sessionsRelated MCP server: remembrallmcp
How It's Different
Tool | Built for | What it remembers | Agent-native |
OB1 / personal memory | One person | Your thoughts and captures | No |
Mem0 / Zep | App developers | User preferences, conversations | Partially |
Confluence / Notion | Human teams | Documentation (human-browsed) | No |
Lore | Engineering teams + AI agents | How your systems actually work — searchable by meaning, not just keywords | Yes |
Lore is not a second brain. It's the operational intelligence your agents need to work in your environment — not just any environment.
What Lore Does
Knowledge Base
Your team's operational knowledge — always queryable by any agent. Capture the things that matter: runbooks, hard-won gotchas, architecture decisions, deployment state. Every entry carries attribution so agents know who wrote it and whether a human has verified it.
Investigations
When something breaks, open a structured investigation. Document the symptom, test hypotheses, record what you tried and what you found. Six months later when the same issue resurfaces — different engineer, different agent — the trail is there.
Journal
A permanent record of milestones, architecture decisions, and buying decisions. The kind of thing that lives in someone's head until they leave the team.
Built for Multi-Agent Systems
In a multi-agent environment, provenance matters. Every Lore entry carries author, source_type, and verified.
kb_search("proxmox lxc dns")
[1] "LXC inherits host resolv.conf — Tailscale breaks containers"
david · human · ✓ verified
[2] "LXC DNS fix after Tailscale install"
engineer-agent · agent · unreviewed
[3] "LXC DNS configuration reference"
research-agent · agent · ✗ disputedYour agents know: result 1 is production-safe. Result 2, spot-check before acting. Result 3, review first.
Semantic Search
Lore finds entries by meaning, not just keywords. Search "DNS broken in containers" and it returns an entry titled "LXC containers inherit resolv.conf from the host" — no keyword overlap required.
Powered by local sentence-transformers embeddings (no API key, no external calls), combined with lexical full-text search and Reciprocal Rank Fusion. The same model used by mcp-memory-service, fully self-hosted. On SQLite the lexical leg uses FTS5; on PostgreSQL it uses a GIN full-text index plus pgvector for the semantic leg.
Enable it
pip install lore-knowledge-mcp[semantic]
LORE_SEMANTIC_SEARCH=true lore-mcpSearch modes
kb_search resolves its mode from (in order): an explicit search_mode/semantic/hybrid argument, then LORE_SEARCH_MODE_DEFAULT, then the built-in default of hybrid. Every search response echoes requested_mode (the caller's intent) alongside search_mode (the mode actually executed, after any degradation).
Mode | When to use |
| Exact term matches. |
| Meaning-based retrieval, no keyword overlap needed. |
| Best of both — lexical + vector via RRF (default). |
The
summarymode was removed — passingsearch_mode="summary"now returns a validation error. Lore is LLM-free by design; summarisation is the caller's responsibility.
Backfill existing KB
If you already have entries, generate embeddings for them:
kb_backfill_embeddings() # idempotent, safe to re-run
kb_embedding_status() # check coverageConfiguration
Variable | Default | Notes |
|
| Master switch — off = lexical-only behaviour. |
|
| Default mode for |
|
| 384d, ~90MB, English-optimized. |
|
| Increase to 30–60 for corpora >10k entries. |
For multilingual content, set LORE_EMBEDDING_MODEL=paraphrase-multilingual-MiniLM-L12-v2 (same 384d, no schema change).
Automatic Memory Extraction
Lore can extract durable memories from agent conversations automatically. At the end of a session, conversation turns are sent asynchronously to a fast LLM, which extracts facts, preferences, goals, events, and system facts — then deduplicates them against the existing KB before writing.
Opt-in — disabled by default (
auto_extract.enabled: false).Two providers — OpenRouter (default, simple setup) or Cerebras direct API (gpt-oss-120b, 300+ TPS, high prompt-cache hit rate).
Graceful degradation — a missing API key, HTTP error, or bad JSON returns an empty result silently; it never raises and never blocks the session.
Auditable — every auto-extracted entry is tagged
source:auto-extracted, with an optional review queue (topic="auto-memory-pending") for human approval.
Set OPENROUTER_API_KEY (or CEREBRAS_API_KEY) and enable it in your plugin config.
→ Full setup guide: docs/auto-extraction-setup.md — API keys, provider config, tuning thresholds, review mode, and inspecting or removing extracted entries.
Automating Lore in Your Workflow
Add one line to every agent's system prompt and one entry to ~/.mcp.json — that's the entire integration. Each phase of your engineering workflow reads prior knowledge from Lore and writes its findings back, so nothing is re-discovered from scratch.
→ How to wire Lore into a 6-phase multi-agent pipeline — full walkthrough with code examples for every phase: research, architecture review, implementation, adversarial code review, QA, and documentation.
Quick Start
No database setup required. Lore runs out of the box with SQLite.
1. Install
pip install lore-knowledge-mcpOptional: semantic search
pip install lore-knowledge-mcp[semantic]Then set LORE_SEMANTIC_SEARCH=true. See Semantic Search for details.
2. Start the server
# Stdio mode (for local MCP clients like Claude Code)
lore-mcp
# HTTP mode (for remote or multi-agent access)
lore-mcp --host 0.0.0.0 --port 8000
# HTTP mode WITH authentication (recommended for teams / LAN exposure)
LORE_API_KEY="$(openssl rand -hex 32)" lore-mcp --host 0.0.0.0 --port 8000Authentication (LORE_API_KEY)
HTTP auth is opt-in and off by default:
LORE_API_KEYunset → the HTTP server is open (no auth), exactly as before. This keeps existing no-auth deployments working. When you bind to a non-localhost host (0.0.0.0or a LAN IP) without a key, Lore logs a prominent startup WARNING that the server is reachable on your network with no authentication.LORE_API_KEYset → every HTTP/SSE request must includeAuthorization: Bearer <key>. Missing or wrong tokens get401 {"error":"unauthorized"}(token compared in constant time). Health endpoints (/health,/healthz,/) stay open so liveness probes keep working. stdio mode is never affected — it has no network surface.
The same rule applies to the HTTP entry point (lore-mcp --host/--port,
which invokes the FastMCP server).
CORS: origins default to * with credentials disabled (the spec forbids
* + credentials). Set LORE_CORS_ORIGINS to a comma-separated allow-list
(e.g. https://app.example.com,https://admin.example.com) to restrict origins;
credentialed CORS is enabled automatically when origins are explicit.
3. Add to your MCP client
Claude Code / Claude Desktop — add to ~/.mcp.json:
{
"mcpServers": {
"lore": {
"type": "stdio",
"command": "lore-mcp"
}
}
}Or for HTTP mode (recommended for teams). When the server is started with
LORE_API_KEY set, include a matching bearer token in the client config:
{
"mcpServers": {
"lore": {
"type": "http",
"url": "http://localhost:8000/mcp",
"headers": {
"Authorization": "Bearer <your LORE_API_KEY>"
}
}
}
}If the server is started without LORE_API_KEY, omit the headers block — the
endpoint is open.
That’s it. Lore is ready.
Tool Reference
Knowledge Base
Tool | What it does |
| Add an entry. Accepts |
| Semantic / hybrid / FTS search with optional topic filter. |
| Fetch full entry by ID. |
| Fetch multiple entries by ID in a single call (re-keyed by |
| List entries, filter by topic. |
| Update content, tags, or set |
| Delete entry (requires |
| Generate embeddings for existing entries (idempotent). |
| Report embedding coverage across the KB. |
Investigations
Tool | What it does |
| Open or add to an investigation. |
| List investigations, filter by topic. |
| Fetch full investigation by ID. |
| Log a structured hypothesis → result → conclusion. |
| List all logged experiments. |
| Hard-delete a note (requires |
| Hard-delete an experiment (requires |
Journal
Tool | What it does |
| Add a milestone, decision, or reflection. |
| List recent entries (default 20). |
| Fetch entry by ID. |
| Hard-delete an entry (requires |
| Snapshot a config object to the journal. |
Document Ingestion
Tool | What it does |
| Ingest a markdown file into the KB ( |
| Batch-ingest a directory, with change detection. |
| Check what's changed since last sync. |
MCP Index
Tool | What it does |
| Scan all configured MCP servers and index their tools. |
| Search indexed tools by description. |
| Get all tools for a specific MCP server. |
| Force a full rescan. |
Search
Tool | What it does |
| Search across KB, investigations, journal, and transcripts at once. |
| Search local files by content. |
| Search Whisper transcript segments. |
| Deduplicate a result set by similarity threshold. |
| Cluster results by topic. |
Backends
SQLite | PostgreSQL | |
Setup required | None | Existing PostgreSQL instance |
Best for | Solo developers, local use | Teams, shared agents, production |
Config |
|
|
Data location |
| Your database |
Semantic search | sqlite-vec + FTS5 | pgvector + GIN full-text index |
SQLite is the default. No configuration needed — just install and run. The
SQLite database and any local-file search corpus live under
KNOWLEDGE_DATA_DIR, which defaults to ./knowledge-data (a portable, relative
path — set it to an absolute path for a stable on-disk location).
PostgreSQL is for teams who want a shared knowledge layer accessible from
multiple machines or agents simultaneously. DB_BACKEND=postgres (and the
postgresql alias) select the bundled local PostgreSQL client — the same path
as DB_BACKEND=local. Connection defaults are generic (DB_NAME=lore,
DB_USER=lore_user); override them with the connection variables below. On
PostgreSQL, hybrid search uses a combined title+content GIN full-text index for
the lexical leg and pgvector for the semantic leg.
# PostgreSQL setup
export DB_BACKEND=postgres # "postgresql" and "local" also work
export DB_HOST=your-db-host
export DB_PORT=5432
export DB_NAME=lore # default: lore
export DB_USER=your-user # default: lore_user
export DB_PASSWORD=your-password
lore-mcpConfiguration reference
Env var | Default | Purpose |
|
|
|
|
| Root for the SQLite DB and local-file search. Portable by default — no |
|
| PostgreSQL database name. |
|
| PostgreSQL user. |
|
| Master switch for semantic/hybrid search (requires the |
|
| Default |
| (unset) | API key for automatic memory extraction via OpenRouter. See Automatic Memory Extraction. |
| (unset) | API key for automatic memory extraction via the Cerebras direct API. |
| (unset) | Optional corpus root for |
| (unset) | Optional transcript root for |
| (unset) | Optional corpora root for |
| (unset) | Opt-in HTTP auth. Set → require |
|
| Comma-separated CORS allow-list. |
The deployment-specific search roots (LATVIAN_LEARNING_ROOT,
LATVIAN_XTTS_ROOT, INGEST_ROOT) are unset by default. When a root is not
configured, the dependent search tool returns an empty, clearly-labelled "not
configured" result instead of scanning a nonexistent path — so a fresh install
works out of the box.
Hermes Memory Provider
A Hermes agent memory provider plugin that backs conversation memory with Lore is available as a separate package:
hermes-lore-plugin — drop-in memory provider for the Hermes agent. Stores KB entries in Lore, prefetches relevant context on session start, and deduplicates before storing. It also drives the automatic memory extraction pipeline.
License
MIT — see LICENSE
Available Tools
42 toolsbackfill_query_embeddingsA
Backfill query_embedding column in retrieval_telemetry for rows that predate Phase 4a. Processes rows in batches. Set build_index=true to also create the HNSW index after backfill.
Inputs: batch_size, limit, dry_run, build_index. Returns: result
cluster_resultsA
Groups search results by source_type (file extension, corpus, transcript). The cluster count is determined by the data, not by a parameter — Issue #22 removed the previously-misleading num_clusters/n_clusters knobs.
Inputs: results (required). Returns: result
deduplicate_resultsC
Remove duplicate search results based on text similarity
Inputs: results (required), threshold. Returns: result
get_hard_negativesA
Read hard negative (query, document) pairs from knowledge.hard_negative_pairs. Filter by signal_type (explicit/behavioral/all), doc_id, or query_text_like. Returns pairs sorted by occurrence_count DESC.
Inputs: signal_type, limit, doc_id, query_text_like. Returns: result
get_retrieval_telemetryA
Read retrieval telemetry rows (issue #5). Selector precedence: query_id > session_id > topic > recent. Returns newest-first.
Inputs: query_id, session_id, topic, limit. Returns: result
get_telemetry_statsA
Aggregate retrieval telemetry stats (issue #5): totals, feedback coverage, requery count, average score, oldest/newest timestamps. Optionally scoped by session_id and/or topic.
Inputs: session_id, topic. Returns: result
investigation_addC
Add an investigation entry (open or append to an ops investigation)
Inputs: topic (required), title (required), content (required), tags. Returns: result
investigation_delete_experimentA
Hard-delete an investigation experiment by experiment_id (Issue #21). Requires confirm=True; in LORE_ENV=production also requires confirm_production=True.
Inputs: experiment_id (required), confirm, confirm_production. Returns: result
investigation_delete_noteA
Hard-delete an investigation note by note_id (Issue #21). Requires confirm=True; in LORE_ENV=production also requires confirm_production=True.
Inputs: note_id (required), confirm, confirm_production. Returns: result
investigation_getB
Get a single investigation entry by ID
Inputs: note_id (required). Returns: result
investigation_listD
List investigations
Inputs: topic. Returns: result
investigation_list_experimentsA
List logged investigation experiments
Inputs: no named parameters. Returns: result
investigation_log_experimentC
Log a structured experiment within an investigation (hypothesis, methodology, results, conclusion)
Inputs: title (required), hypothesis, methodology, results, +1 more. Returns: result
journal_appendC
Append journal entry
Inputs: entry_type (required), content (required), tags. Returns: result
journal_deleteA
Hard-delete a journal entry by entry_id (Issue #21). Requires confirm=True; in LORE_ENV=production also requires confirm_production=True.
Inputs: entry_id (required), confirm, confirm_production. Returns: result
journal_getC
Get journal entry
Inputs: entry_id (required). Returns: result
journal_listC
List journal entries
Inputs: limit. Returns: result
journal_searchC
Full-text search across journal entry content (Issue #15)
Inputs: query (required), limit, entry_type, date_from, +1 more. Returns: result
kb_addC
Add a knowledge base entry
Inputs: topic (required), title (required), content (required), tags, +3 more. Returns: result
kb_backfill_embeddingsA
Embed any KB entries that are missing or stale (model/content changed). Idempotent: skips entries whose stored content_hash still matches. Requires LORE_SEMANTIC_SEARCH=true.
Inputs: batch_size, limit, dry_run, confirm_production. Returns: result
kb_deleteC
Delete existing KB entry from database
Inputs: kb_id (required), confirm. Returns: result
kb_embedding_statusA
Report embedding coverage: total entries, embedded count, missing count, current model, and per-model breakdown.
Inputs: no named parameters. Returns: result
kb_getB
Get full KB entry by ID
Inputs: kb_id (required). Returns: result
kb_get_batchB
Fetch full content for multiple KB entries by ID. Use after kb_search to retrieve content without N+1 round trips.
Inputs: kb_ids (required). Returns: result
kb_ingest_dirC
Batch ingest directory of markdown files
Inputs: dir_path (required), pattern, strategy, recursive, +4 more. Returns: result
kb_ingest_docC
Ingest single markdown file into KB with change detection
Inputs: doc_path (required), strategy, chunk_size, tags, +3 more. Returns: result
kb_listC
List KB entries
Inputs: topic, limit, offset. Returns: result
kb_searchB
Search knowledge base. Lexical FTS5 (or LIKE fallback) by default; set semantic=true / hybrid=true / search_mode=hybrid to use vector embeddings + RRF fusion (requires LORE_SEMANTIC_SEARCH=true).
Inputs: query (required), topic, top_k, semantic, +8 more. Returns: result
kb_sync_statusC
Check sync state between source docs and KB
Inputs: dir_path. Returns: result
kb_updateB
Update existing KB entry content, title, topic, tags, verified state, and trust_score
Inputs: kb_id (required), content, title, tags, +3 more. Returns: result
log_retrieval_feedbackA
Score or annotate a prior kb_search result by its query_id (retrieval telemetry, issue #5). Supply user_feedback_score, required_requery, notes, or any combination; an omitted field is left unchanged (cannot be reset to null). No effect unless LORE_HARD_NEGATIVE_MINING=true on a PostgreSQL backend.
Inputs: query_id (required), user_feedback_score, notes, required_requery. Returns: result
mcp_index_get_serverC
Get all tools for a specific MCP server
Inputs: server_id (required). Returns: result
mcp_index_get_toolC
Get detailed information about a specific tool
Inputs: tool_name (required). Returns: result
mcp_index_rebuildB
Force rebuild of entire MCP index (same as mcp_index_scan)
Inputs: no named parameters. Returns: result
mcp_index_scanB
Scan all MCP servers and index their tools. By default, scans only configured servers (66% token savings).
Inputs: triggered_by, config_filter. Returns: result
mcp_index_searchC
Search for MCP tools by description/capability
Inputs: query (required), category, limit. Returns: result
multi_searchA
Search across all configured sources simultaneously (KB, local files, transcripts, corpora) with a single query. Returns combined results from all available sources. For searching within a specific source only, use kb_search, search_local, search_transcripts, or search_corpora instead.
Inputs: query (required). Returns: result
refresh_hard_negativesA
Scan retrieval_telemetry for low-scored and requery signals, then upsert hard negative pairs into knowledge.hard_negative_pairs. Use since= for incremental refresh. dry_run=true returns counts without writing. Requires LORE_HARD_NEGATIVE_MINING=true.
Inputs: since, dry_run. Returns: result
search_corporaC
Search across corpus manifests (JSONL files)
Inputs: query (required), corpus_ids. Returns: result
search_localC
Search local files by content (lexical mode)
Inputs: query (required), paths, file_types. Returns: result
search_transcriptsC
Search transcript segments from Whisper outputs
Inputs: query (required), speaker. Returns: result
snapshot_configD
Snapshot current config
Inputs: config_name (required), config_data (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 42 tools
Most tools are cleanly separated by domain prefixes and detailed descriptions, but mcp_index_scan and mcp_index_rebuild are effectively the same operation, and the many search-related tools (kb_search, search_local, search_corpora, search_transcripts, multi_search) require careful reading to avoid mis-selection.
The naming is largely consistent: snake_case verb_noun patterns with domain prefixes like kb_, investigation_, journal_, and mcp_index_. Minor inconsistencies exist, such as mcp_index_scan/mcp_index_rebuild being duplicate operations and backfill_query_embeddings not following the kb_backfill_embeddings prefix style, but the overall pattern is predictable.
42 tools is far too many for a single MCP server, even one spanning knowledge bases, investigations, journals, search, telemetry, and MCP indexing. The surface would be more usable split into smaller focused servers or consolidated into fewer higher-level tools.
The knowledge base has full CRUD plus ingestion and embedding workflows; investigations, journals, search, telemetry, and MCP indexing all cover their core lifecycles. Minor gaps like no explicit investigation or journal update operation are likely intentional given the append-oriented design, but they are still notable omissions.
Maintenance
Related MCP Connectors
Universal persistent memory and knowledge retrieval layer for AI agents and LLMs.
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Persistent memory for AI agents. Search and store durable facts, preferences and decisions.
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides AI agents with persistent, searchable memory using a knowledge graph stored in SQLite. Features semantic search, temporal awareness, and workflow-aware prompts for development projects.7 npmMIT
- AlicenseNot gradedqualityCmaintenancePersistent knowledge memory layer for AI agents. Hybrid semantic + full-text search with pgvector, code dependency graph with blast-radius impact analysis, and incremental indexing for 7 languages. In-process ONNX embeddings, no external API required.51 npm47 PyPI35MIT
- AlicenseNot gradedqualityDmaintenanceGives AI coding agents persistent memory by storing observations, decisions, and learnings in a local SQLite database with vector search, full-text search, and a rules engine.4MIT
- FlicenseAqualityDmaintenanceA persistent, cross-session knowledge base for AI agents that indexes session history into a searchable SQLite database with full-text search, enabling recall of past sessions, stored knowledge, and summaries.10-