Browse your knowledge graph in the browser.
A knowledge-graph console and brain — force-directed graph, dashboard, hybrid search, and durable agent memory, on your own Postgres.
Quickstart · Deploy · Configure · Contribute
Lore is a web console for a personal knowledge graph — your notes, people, projects, and the links that connect them — rendered as a force-directed graph, a dashboard, and hybrid search, so you can see and walk your knowledge instead of grepping it.
It serves its own brain out of Postgres + pgvector — no other backend to run. The browser console holds only the reading credential: every write (vault import, put_page, remember) needs an explicit bearer token and never rides your viewer session.
- Force-directed graph — d3 node-link view with smooth zoom/pan, click-to-filter by type, and connection-walking from any node.
- Dashboard — pages, links, sources, daily activity, top hubs, and recent memories at a glance.
- Hybrid search — vector + keyword + trigram, rank-fused, as you type.
- Bring your Obsidian vault — pick a folder at
/import; files become pages, folders become slug prefixes, and[[wikilinks]]become edges (including the ones in frontmatter, Markdown-style links, and aliases). Export the whole brain back out as a tar ofslug.mdfrom/api/export. - Agent memory — an immutable event log, versioned thread summaries, and typed durable memories with provenance, supersession and historical (
as_of) recall. Agents useremember/recall/forget/inspect_memory; memories are projected into the same graph and search as everything else, and a correction supersedes rather than overwrites. - Graph health — the dashboard names the two reasons a graph looks empty: links pointing at pages that don't exist, and pages nothing points at.
- Pluggable viz modules — drop in a new
src/lib/viz/<name>.tsto add a visualization. - Fail-closed auth — none (dev), HTTP Basic, or a trusted gateway (JWT- or secret-verified; never a bare identity header). The console holds only the reading credential; writes need their own
BRAIN_WRITE_TOKEN. - Deploy anywhere — standalone Docker image; one-click to Vercel or Railway.
Bring only a Postgres with pgvector and pg_trgm (e.g. a free Neon database). PostgreSQL 12 or newer; tested on 17 and 18. Lore serves its own brain: hybrid search (vector + keyword + trigram), a wikilink graph, and an MCP endpoint at POST /api/mcp your agents can write memories to (put_page / remember_note / delete_page for pages, remember for agent memory; bearer BRAIN_WRITE_TOKEN).
git clone https://github.com/corespeed-io/lore.git && cd lore
cp .env.example .env # set DATABASE_URL + EMBEDDINGS_*
npm install && npm run dev # → http://localhost:3000Lore exposes MCP at POST /api/mcp — spec revision 2026-07-28, with the 2025 handshake revisions still served for older clients. Point any MCP client at it with the write bearer:
claude mcp add --transport http lore http://localhost:3000/api/mcp --header "Authorization: Bearer $BRAIN_WRITE_TOKEN"bin/lore.mjs is a zero-dependency CLI over the same endpoint — it reads .env from the working directory, so a checkout needs no configuration:
./bin/lore.mjs search "what did we decide about auth"
./bin/lore.mjs put notes/standup --title "Standup" < notes.md
./bin/lore.mjs health # orphans + broken links
./bin/lore.mjs sweep --dry # what mention-linking would connectlore with no arguments lists every command. Point it elsewhere with LORE_URL / LORE_TOKEN.
Lore ships three SKILL.md files — an open standard read by 70+ agents, and the same file works in all of them.
npx skills add corespeed-io/loreThat installs them into whichever agent you use — vercel-labs/skills reads skills/ straight out of this repo, so there is no npm package and no clone. From a checkout, npx skills add . does the same thing.
- lore-brain — which write door (
put_page/remember_note/remember) and which read door (search/recall/ the graph) - lore-memory — scopes, supersession,
as_ofrecall, the event log - lore-curate — orphans, broken links, renames, the background jobs
Lore fails closed. A fresh deploy returns
403until you setAUTH_MODE—gatewayorpassword, ornonewithALLOW_INSECURE=1. It will not serve a private brain by accident.
Lore is a standard Next.js standalone app, so it also runs on Railway (Dockerfile auto-detected) or any container host:
docker build -t lore . && docker run -p 3000:8080 --env-file .env loreOr on Cloudflare Workers (via OpenNext) — put any Postgres behind a Hyperdrive binding (free plan included; see wrangler.jsonc):
npx wrangler hyperdrive create lore-db --caching-disabled --connection-string="postgres://…"
npx wrangler secret put EMBEDDINGS_API_KEY # + BRAIN_WRITE_TOKEN, UI_PASSWORD…
npm run cf:deployConfig is entirely environment-driven — see .env.example for the full list.
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL |
yes | Postgres 12+ with vector + pg_trgm |
EMBEDDINGS_URL / _API_KEY / _MODEL / _DIM |
yes | Any OpenAI-compatible endpoint, including a local ollama |
EMBEDDINGS_QUERY_PREFIX |
no | Prepended to queries only — the instruction the 2026 models want |
BRAIN_WRITE_TOKEN / BRAIN_READ_TOKEN |
yes | Agents' bearer for the MCP endpoint; ≥16 chars or refused |
APP_TITLE / APP_SUBTITLE |
no | Hero branding, per deployment |
AUTH_MODE |
no | none · password · gateway. Defaults to none |
ALLOW_INSECURE |
no | Required to actually run with AUTH_MODE=none (auth fails closed otherwise) |
AUTH_GATEWAY_JWKS_URL / _ISSUER / _AUDIENCE |
for gateway | Verify a JWT the gateway signed — Cloudflare Access sends one already |
AUTH_GATEWAY_SHARED_SECRET |
for gateway | Or a secret header, if your proxy can't sign a JWT |
AUTH_GATEWAY_USER_HEADER |
no | Where identity arrives (default X-Forwarded-User), read only after a proof holds |
Auth fails closed, and a half-configured mode is an error rather than an opening — AUTH_MODE=password with no UI_PASSWORD is refused, not downgraded. gateway never trusts an identity header on its own: it reads X-Forwarded-User only after verifying a JWT or a shared secret, and refuses every request if neither is configured. Never expose the origin with ALLOW_INSECURE=1 to the internet.
// src/lib/viz/<name>.ts
export function mountName(el: HTMLElement, data: GraphData, opts: Opts): Instance {
// render with d3, canvas, or the DOM; return { destroy, ... } for teardown
}Mount it from src/components/GraphView.tsx and add a test in tests/.
npm run dev # dev server (hot reload)
npm run typecheck # tsc --noEmit
npm run lint # biome
npm test # vitest
npm run build # production buildWorking with an AI coding agent? AGENTS.md is the single source of truth — Claude Code, Codex, Cursor, Gemini, and Copilot all read it.
Issues, ideas, and PRs are welcome — start with CONTRIBUTING.md or open a discussion. Built and maintained by CoreSpeed.
MIT © CoreSpeed

