A shared memory for engineering teams and their AI agents.
Today, the useful technical facts an engineer surfaces in a 1:1 AI chat — why a service is configured a certain way, which migration broke prod, what the gotcha in the deploy script is — die in that conversation. Fornix is a small MCP server that captures those facts in a shared, searchable store, so knowledge flows between teammates and agents instead of siloing one chat at a time.
Status: Phase 1 (MVP). A single-user remember → review → recall loop over Postgres + pgvector. The schema already reserves room for confidence scoring and staleness decay; those layers come later (see Scope).
- Remember — an agent stores a fact. It lands as a
draft. - Review — a human promotes it to
confirmed, sends it back todraft, orrejecteds it (kept for audit). - Recall — agents semantically search the store, optionally filtering to only
confirmedfacts.
Every recall also bumps each hit's last_seen_at, so a staleness signal is quietly accumulating for future phases.
uv sync --all-extras # create the venv and install deps (incl. dev + openai extras)
cp .env.example .env # copy default config
just up # start Postgres + pgvector (docker compose, port 5433)
just migrate # apply the schema
just test # run the test suite
just run # start the MCP server over stdiojust with no recipe lists everything available (down, nuke, lint, fix, psql, …).
The tools read like requests you'd make to a colleague — verb-forward and neutral.
| Tool | What it does |
|---|---|
remember |
Store a fact as a new draft entry |
recall |
Semantic search for entries on a topic (optional status filter) |
review |
Promote a draft, demote it, or reject it — with an optional note |
forget |
Delete an entry by id, or by closest semantic match (guarded by min_score) |
browse_memory |
List recent entries, or search the whole store (optional status filter) |
memory_summary |
Counts, a per-status breakdown, and a sample of recent entries |
Entries begin as draft. A reviewer calls review(entry_id, status="confirmed") — optionally with a note explaining why — to promote it. status="draft" demotes a confirmed entry back for another look. status="rejected" is terminal: the entry stays for audit but is hidden from status="confirmed" recalls. Clients that only want vetted facts pass status="confirmed" to recall.
A full remember → recall → review loop. The calls are made by an MCP client (an AI agent); the JSON is what Fornix returns.
1. An agent stores something it just figured out:
remember(
content="Staging deploys must run `just migrate` before `just up` — otherwise pgvector isn't registered and the first query 500s.",
source_ref="https://github.com/acme/infra/pull/412",
)
→ { "id": "a3f1c9de", "status": "draft" }
2. Days later, a teammate's agent goes looking:
recall(topic="why does the staging deploy fail on the first query?")
→ {
"topic": "why does the staging deploy fail on the first query?",
"results": [
{
"id": "a3f1c9de",
"content": "Staging deploys must run `just migrate` before `just up` …",
"score": 0.82,
"status": "draft",
"created_at": "2026-05-27T09:14:00+00:00",
"source_ref": "https://github.com/acme/infra/pull/412"
}
]
}
3. A reviewer vets it and promotes it:
review(entry_id="a3f1c9de", status="confirmed", note="Hit this in the May incident — confirmed.")
→ {
"previous_status": "draft",
"new_status": "confirmed",
"entry": { "id": "a3f1c9de", "status": "confirmed", "review_note": "Hit this in the May incident — confirmed.", … }
}
From now on, agents that want only vetted knowledge call recall(topic=…, status="confirmed") and this fact comes back.
Add Fornix to ~/.claude.json (at the project or user level):
{
"mcpServers": {
"fornix": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/fornix", "run", "fornix"]
}
}
}Retrieval quality depends on the embedder:
dummy(default) — a deterministic hash → vector. Perfect for bring-up and tests, useless for real semantic search.openai— setFORNIX_EMBEDDER=openaiandOPENAI_API_KEYin.env.
The embedding dimension (FORNIX_EMBEDDING_DIM, default 1536) must match the embedder you choose.
Phase 1 is deliberately the smallest thing that can store and surface a fact — the goal is to learn what good extraction rules and retrieval relevance look like in practice before building more. Out of scope for now:
- Confidence scoring and staleness/decay jobs (the
confidenceandlast_seen_atcolumns exist, but nothing acts on them yet) - Multi-user, auth, and reviewer consensus
- Conflict detection and typed relationships / knowledge graph
- Auto-extraction of facts from conversations
- Any non-MCP surface (REST API, dashboard)
Closest neighbour is doobidoo/mcp-memory-service, a mature personal-AI memory service. Fornix makes three different bets:
- Team-first, not personal-first. mcp-memory-service assumes one trusted user; Fornix's north star is knowledge flowing between teammates and agents.
- Human-in-the-loop curation. Its "approval" is tool-call safety annotations (read-only vs. destructive), not content review. Fornix's
reviewworkflow plus thestatusfilter let clients ask for only confirmed facts. - A deliberately narrow surface. MCP stdio only — no REST or dashboard — while the extraction/retrieval loop is still being tuned.
- Multi-reviewer consensus and a review-history table (today only the latest review is kept)
- Staleness/decay jobs driven by
last_seen_at(tracking works; the logic doesn't exist yet) - Confidence scoring layer over the reserved
confidencecolumn - Revisit a read-only REST surface or small dashboard once multi-user lands
- Evaluate typed relationships / a knowledge graph for conflict detection