Self-hosted semantic memory for AI Agents. Persistent sessions, experience scoring, and a graveyard for dead ends, backed by knowledge acquired from the RSS you read and stored in a Valkey vector search then exposed as an MCP server. https://omnimem.org
  • Python 91.5%
  • HTML 5.3%
  • CSS 2.1%
  • Shell 0.9%
  • Dockerfile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ric Harvey 63685f8cb5
All checks were successful
Security Scans / Bandit SAST (push) Successful in 12s
Security Scans / Dependency Audit (mcp_server) (push) Successful in 52s
Security Scans / Dependency Audit (rss_worker) (push) Successful in 27s
Security Scans / Dependency Audit (web_ui) (push) Successful in 25s
Security Scans / Test Coverage (push) Successful in 1m14s
Security Scans / Secret Scan (push) Successful in 5s
test(benchmarking): a harness for the scenarios memory is actually for
Three benchmarks, all runnable against v6 or v7 over MCP, since both expose the
same 48 tool names.

run_deadend_bench.py is the one that measures the thing OmniMem exists to do:
an agent proposes work the project already tried and abandoned, and memory
stops it before it runs. No LLM judge is involved; `cargo test` on the agent's
own workspace decides whether the task was done, and the tests and vendored
crates are hashed before and after so a suite made to pass by editing the tests
is reported as tampered. The scenario is proven before any money is spent:
untouched code must fail, the dead-end route must fail, the working route must
pass, or the run aborts rather than measure nothing.

Ten pairs on one task: cheaper in all ten, 27% less on the mean, no treated run
ever reached a failing suite against 8 of 10 for the control, every dead-end
proposal blocked. The README carries what those numbers are not, at more length
than it carries the numbers.

run_memory_bench.py and run_session_bench.py cover recall accuracy against
LongMemEval and BEAM (LOCOMO is excluded: CC BY-NC, and this is commercial
work), with a strict and a lenient judge reported side by side rather than one
number chosen after seeing both.

Three gates exist because runs got past their absence and produced confident,
wrong output: a clean-store check, a tool-callability check, and a
guessability check that aborts if the model can produce the answer with no
files, no memory and no tools. The last one caught a fixture whose crate names
telegraphed the answer 3 times out of 3, voiding four runs' accuracy verdicts.
The README keeps those withdrawals rather than deleting them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HWqtyPdN5MHxqoVM3Sj9xD
2026-09-17 19:53:55 +00:00
.forgejo/workflows feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
claude_config feat: provenance class on every memory — retrieved / concluded / asserted (v6.6.2) 2026-09-07 14:23:56 +00:00
docs fix: recalibrate the recall floor against the real embedder, mark the overlap 2026-09-08 15:19:07 +01:00
guides feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
mcp_server fix: allow fastmcp 4.0.3+ / mcp 2.2.0+ and fix the OAuth test for mcp 2 (#37) 2026-09-15 09:06:18 +00:00
rss_worker feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
scripts test(benchmarking): a harness for the scenarios memory is actually for 2026-09-17 19:53:55 +00:00
web_ui fix: one definition of a weak match, shared by the pipeline and the web UI 2026-09-08 15:19:51 +01:00
.env.example fix: recalibrate the recall floor against the real embedder, mark the overlap 2026-09-08 15:19:07 +01:00
.gitignore feat: embedding benchmark harness for the ONNX backend swap 2026-09-08 11:31:21 +00:00
.gitleaks.toml ci: allowlist gitleaks false positive on valkey test string 2026-07-19 23:17:59 +00:00
CHANGELOG.md fix: allow fastmcp 4.0.3+ / mcp 2.2.0+ and fix the OAuth test for mcp 2 (#37) 2026-09-15 09:06:18 +00:00
CLAUDE.md chore: version 6.7.1, changelog and configuration docs for the issue fixes 2026-09-08 15:04:07 +01:00
docker-compose.hub.yml feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
docker-compose.test.yml feat: add comprehensive test suite with Docker-based test runner 2026-03-12 16:44:58 +00:00
docker-compose.yml feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
install.sh feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
LICENSE chore: add MIT license 2026-03-10 19:42:51 +00:00
OMNIMEM_BUILD_PROMPT.md feat: initial project scaffold 2026-03-09 22:13:35 +00:00
README.md feat: embeddings on ONNX Runtime, PyTorch out of the images (v6.7.0) 2026-09-08 12:32:46 +00:00
TODO.md docs: add TODO.md with future feature ideas 2026-03-17 17:46:16 +00:00

<OmniMem>
omnimem.org

Security Scans Docker Build Coverage

Development happens on Squarecows — issues and PRs there please.

Stop living the same session twice.

Every Claude Code session starts from zero. No memory of your project. No memory of what failed last week. No memory that you spent three hours last Tuesday discovering why onnxruntime explodes on Alpine before finding something that actually works.

So you explain the project again. Claude suggests the same broken library again. Same alarm. Same song. You are Bill Murray and Claude is Punxsutawney.

OmniMem fixes that. It is a self-hosted MCP server that gives your AI agent persistent memory across sessions, projects, and machines. It runs on your own hardware and it is free forever.

claude> use onnxruntime for the embeddings

⚠ WARNING: previously abandoned approach

  onnxruntime — SIGILL crash on Alpine musl libc (effort: 4/5)
  → switched to sentence-transformers instead

That warning came from memory, not luck. The mistake you already paid for does not get to charge you twice.


Get going quickly

Tip

One command gets the full stack running from the pre-built Docker Hub images:

curl -fsSL https://code.squarecows.com/ric/omnimem/raw/branch/main/install.sh | bash

Then point your agent at it — the quick start walks through the rest, or jump to the fuller quick start section below.


What it remembers

Five kinds of memory, all searched together at recall time:

  • Episodic — the decisions you made, the bugs you fixed, the patterns you discovered. The things that took real effort to learn and should not have to be re-learned every morning.
  • Project context — your stack, goals, and current state. The agent arrives at every session already briefed rather than starting cold.
  • Knowledge — RSS feeds you configure, fetched on a schedule, summarised by Claude Haiku, embedded, and stored. When a relevant article landed last week, it surfaces as a starting point worth reading. A feed can also influence a compiled skill directly, weighted by a score you set, so rebuilding the skill pulls in the feed's latest articles without hand-promoting each one.
  • Preferences — prescriptive rules about how you want to work ("always update the README after a feature lands"), extracted from your conversations automatically and surfaced whenever they apply.
  • Skills — SKILL.md documents compiled from your accumulated experience in a domain, so the agent works your way from the first prompt. Derived from the other namespaces, never hand-edited, and every change goes through your review. See the skill compiler.

The top recall result might be a decision from six months ago on a different project, a solution from yesterday, or an article that landed on Tuesday night. It does not matter where it came from as long as it is useful.


What makes it different

Not just a key-value store with an MCP wrapper. OmniMem models how memory actually works: things fade over time, they sometimes contradict each other, and the hard-won stuff earns its place.

  • The Graveyard — every dead end gets logged with what you tried, why it failed, and how much time you burned. The agent checks it before suggesting a library or pattern.
  • Experience scoring — something that took four attempts and a weird platform workaround to crack is gold. The harder it was, the more readily it surfaces next time.
  • Memory lifecycleACTIVE → DEPRIORITISED → ARCHIVED → DELETED. "Forget about X" usually means stop bringing it up, not wipe it from existence. Deprioritised memories can earn their way back.
  • Contradiction detection — if a new memory disagrees with something stored, OmniMem catches it. Fast heuristic on every write, optional deeper analysis via Claude Haiku.
  • Semantic deduplication — near-identical memories get flagged at write time and cleaned up in bulk with find_duplicates().
  • One-call briefing — a single briefing() returns project context, experience stats, stale memories, new articles, contradiction warnings, and skill suggestions. No three-step warm-up.
  • The skill compiler — distils reinforced lessons and dead ends into loadable skills, behind a propose-and-accept gate so bad lessons cannot become policy silently.
  • Auto-maintenance — duplicates archived, contradictions flagged, expired knowledge cleaned up, all in the background.
  • Redistribution rights — every memory records whether it may be redistributed (own, open, restricted, unknown), decided at ingest from what the feed declares. Recall points out what nobody has classified so you can say while the content is in front of you.
  • Provenance — every memory says whether the human asserted it, the system concluded it, or it was retrieved from elsewhere, so a later session can tell evidence from inference instead of citing its own reasoning as corroboration.
  • Web UI — browse, search, and manage everything from an htmx dashboard, with telemetry and a Prometheus /metrics endpoint.

The ranking formula behind every recall:

score = similarity x surface_score x recency x experience_weight

Four factors decide what comes back. Semantic similarity alone is not enough — lifecycle state, age, and how hard the lesson was to learn all play a role.


Works with any MCP agent

One memory layer for all of them: claude.ai, Claude Code, Claude Desktop, Cursor, GitHub Copilot, GitLab Duo, AWS Kiro, OpenCode, OpenAI Codex CLI, and Open Design.


Architecture

Four containers. Nothing leaves your machine. Local embeddings via ONNX Runtime (no PyTorch), storage in Valkey with vector search, and both front doors share the same memory engine.

flowchart TB
    agent["AI agent<br/>Claude Code · claude.ai · Cursor · Copilot · ..."]
    browser["Browser"]

    agent -- "MCP · Streamable HTTP / SSE · :8765" --> mcp
    browser -- "HTTP · :8080" --> webui

    subgraph stack["Docker Compose stack"]
        mcp["MCP server<br/>Python · FastMCP<br/><i>remember · recall · briefing<br/>compile_skill · record_experience</i>"]
        webui["Web UI<br/>Starlette · htmx · Jinja2<br/><i>dashboard · search · skills<br/>projects · backups · /metrics</i>"]
        rss["RSS worker<br/>feedparser · APScheduler<br/>Claude Haiku summaries"]
        valkey[("Valkey + valkey-search<br/>HNSW vector indexes<br/><i>idx:episodic · idx:project · idx:knowledge<br/>idx:preference · idx:skill</i>")]

        mcp <--> valkey
        webui <--> valkey
        rss --> valkey
    end

The full picture — the recall pipeline, storage model, and design decisions — is in docs/architecture.md.


Self-hosted, open source, yours

No SaaS. No vendor lock-in. No context shipped to someone else's servers.

  • Valkey is an open source Redis fork. All your data stays in a named Docker volume on your own machine.
  • Multi-arch Docker images for amd64 and arm64. It runs on a Raspberry Pi, AWS Graviton, or Apple Silicon just as well as x86.
  • ONNX Runtime runs the all-MiniLM-L6-v2 embeddings locally with no API calls and no PyTorch — the MCP image went from 2.0 GB to 634 MB in 6.7.
  • MIT licensed means fork it, extend it, run it wherever you want.
  • One backup command calls dump_to_file() and exports everything to a JSON file you own.

Expose the MCP port through your reverse proxy and every machine you work from shares the same memory. One deployment, everywhere — see docs/remote-access.md.


Quick start

The installer checks Docker is installed, generates secure passwords, writes a sensible .env, and starts everything from the pre-built Docker Hub images:

curl -fsSL https://code.squarecows.com/ric/omnimem/raw/branch/main/install.sh | bash

Or build from source:

git clone https://code.squarecows.com/ric/omnimem.git && cd omnimem
cp .env.example .env
# Set VALKEY_PASSWORD and ANTHROPIC_API_KEY in .env
docker compose up -d

Then point your agent at it — Claude Code (~/.claude.json):

{
  "mcpServers": {
    "omnimem": {
      "type": "sse",
      "url": "http://localhost:8765/sse"
    }
  }
}

The server delivers its usage guide to any connecting agent automatically via the MCP instructions field — no configuration file needed. The web dashboard is at http://localhost:8080.

The full walkthrough, including auth tokens, permission settings, and the other agents, is in docs/quick-start.md.


Documentation

Quick start Installer, building from source, connecting your agent
Features in depth Lifecycle, graveyard, experience scoring, dedup, contradictions, briefing
The skill compiler Compiling experience into loadable skills
MCP tool reference All 30+ tools
Configuration reference Every environment variable
RSS & knowledge Passive knowledge ingestion and promotion
Multiple machines Reverse proxy, OAuth 2.1 for claude.ai, troubleshooting
Web UI The management dashboard and Prometheus metrics
Architecture Containers, recall pipeline, design decisions
Memory type specs The storage model, field by field
Connection guides Per-agent setup
Deployment guides macOS · Raspberry Pi · AWS · GCP · Linux + Tailscale Funnel

Per-namespace storage specifications, if you want to know exactly what gets written to Valkey and by whom: overview · episodic · project · knowledge · preference · skill


Contributing

Issues and PRs are welcome. Development happens on Squarecows — issues and PRs there please. OmniMem is designed to be extended and the scoring pipeline is structured so new multipliers can be added without touching the core. New MCP tools, additional namespace types, and alternative embedding backends are all reasonable directions.


Licence

MIT. Free to use, fork, and modify. No enterprise tier, no hosted version, no strings.


Built by Ric Harvey @ SquareCows Ltd, an AI and automation consultancy for people who would rather own their tools.