Open source · Self-hosted · Free forever

Stop living the same session twice

A self-hosted MCP server that gives your AI agent persistent memory across sessions, projects, and machines. Everything runs on your hardware — and it's free.

claude — recall
$ claude
claude> recall("markdown editor preferences")
→ merged from 4 namespaces, re-ranked
[episodic] you prefer Typora for long-form
[knowledge] Obsidian 1.6 adds live preview
[project] repo ships docs as .mdx
[graveyard] abandoned: remark pipeline (effort 4/5)
claude>
Install OmniMem
curl -fsSL https://code.squarecows.com/ric/omnimem/raw/branch/main/install.sh | bash

Paste that into your terminal — or follow the manual setup below.

Model-agnostic Any agent that speaks MCP —
one memory layer for all of them.
01 The problem

Every session starts from zero

Your AI agent doesn't know your project. It doesn't remember what failed last week. It has no idea you spent three hours last Tuesday figuring out why onnxruntime crashes on Alpine, only to find something that actually works.

So you explain everything again. It suggests the same broken library again. Same alarm, same song. It's Groundhog Day — you're Bill Murray, and your agent is Punxsutawney.

// without omnimem
claude> use onnxruntime for the embeddings
... 45 minutes of debugging later ...
SIGILL: illegal instruction (Alpine musl libc)
You fixed this exact problem last Tuesday.
Claude doesn't know that.
// with omnimem
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
02 See it in action

One recall() pulls context from everywhere

Personal preferences, ingested articles, past conversations, project context. It's all ranked together and merged into one useful response.

claude — recall
what tools do we know about that are useful for writing markdown in?
omnimem · recall (MCP) (query: "markdown editors and writing tools", top_k: 10)
└ {"result":[{"namespace":"knowledge","content":"Announcing Autosave & More…","score":0.334,"state":"active"}, …
… +70 lines (ctrl+o to expand)
From memory, here's what we know about markdown writing tools:
You actively use:
- Vim — your go-to editor for everything, including markdown episodic
- Apostrophe — you wrote a PiSource article about it, a GNOME markdown editor knowledge
From the self-hosted / FOSS knowledge base:
- Ghost (MIT, Node.js) — markdown blogging platform you wrote about
- WriteFreely (AGPL-3.0, Go) — federated markdown blogging
- BookStack (MIT, PHP) — wiki with markdown support external
- Wiki.js (AGPL-3.0, Node.js) — wiki with markdown editor
- Docmost (AGPL-3.0, Docker) — Confluence alternative
CMS with markdown support: project
- Sveltia CMS and DecapCMS — both work with Forgejo/Gitea backends
That's the lot — pulled from your conversations, your articles, a repo you trained it on, and your Forgejo preference, all ranked together.
nope that's great — you reminded me of exactly what I use
Glad it worked well. OmniMem connected your preferences and past writing into one useful answer.
A real recall() about markdown editors. Every tagged line traces back to a different memory source — see the four on the right.
[episodic]
Episodic memory

Picked up from your conversations — preferences, decisions, and things mentioned in passing.

[knowledge]
Knowledge base

RSS articles, auto-summarised and embedded. They surface when relevant to what you're asking.

[external]
External references

Links and posts you've shared — GitHub threads, blog posts, anything worth holding onto.

[project]
Project context

Extra context it knows matters to you, like your preferred tools and platforms.

03 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.

01 · graveyard

The Graveyard

Every dead-end gets logged — what you tried, why it failed, how much time you burned. Your agent checks the graveyard before suggesting a library or pattern.

02 · scoring

Experience scoring

Something that took four attempts and a weird platform workaround to crack? That's gold. The harder it was, the more prominently it surfaces next time.

03 · integrity

Contradiction detection

If a new memory disagrees with something stored, OmniMem catches it. Fast check on every write, plus optional deep analysis powered by Claude on demand.

04 · dedup

Semantic deduplication

New memories get compared against what's there. Too similar? You get a heads-up instead of a duplicate. Run find_duplicates to clean up in bulk.

05 · namespaces

Three namespaces

Episodic for decisions and bugs. Project for stack and state. Knowledge for RSS articles. All searched together.

06 · briefing

One-call briefing

One briefing() and your agent gets project context, experience stats, stale memories, new articles, and contradictions. No three-step warm-up.

07 · dashboard

Web UI dashboard

Browse, search, and manage memories from an htmx interface. RSS feeds, project contexts, backups, memory details — all without the command line.

08 · telemetry

Telemetry & metrics

Every recall tracks which memories get used. Recall counts and last-accessed per memory, plus a Prometheus /metrics endpoint for Grafana.

09 · maintenance

Auto-maintenance

Every few briefings, OmniMem scans for duplicates and runs a heuristic contradiction check. Stale duplicates archived, conflicts flagged — in the background.

04 Lifecycle

Memory is not binary

Most systems either remember or delete. OmniMem has a proper lifecycle. When you say "forget about X" you usually mean stop bringing it up, not wipe it from existence.

ACTIVE
1.0× weight
DEPRIORITISED
0.2× weight
ARCHIVED
0.0× weight
DELETED
gone

Deprioritised memories aren't gone for good. Attach reinstate hints, and if a future query matches, the memory comes back with a note explaining why it was pushed down. You can mute entire topics across all sessions.

// final ranking
score = similarity × surface_score × recency × experience_weight

Four factors decide what comes back. Semantic similarity alone isn't enough — lifecycle state, age, and how hard it was to figure out all play a role.

Effort
Meaning
Weight
1
Worked first time
1.0×
2
Minor friction
1.1×
3
Multiple iterations
1.25×
4
Significant struggle
1.5×
5
Battle-hardened
1.8×
05 Skills

Skills that build — and evolve — themselves

Memories tell an agent what happened. A skill tells it how you work. OmniMem compiles skills from the work you actually did — the breakthroughs, the recurring gotchas, the graveyard of dead ends — and as new experience lands, the skill evolves with it.

A PATTERN EARNS A RULE

One-off episodes don't compile. A lesson must recur before it becomes policy — or be blessed to jump the queue.

NOTHING WRITES SILENTLY

Every compile proposes a reviewable diff. Rewrites of existing rules are flagged loudly; nothing commits until you accept.

DERIVED, NEVER HAND-EDITED

Memories are the source of truth; the skill is build output. To change the guidance, update the memories and recompile.

SUGGESTED, NEVER AUTO-LOADED

The briefing recommends relevant skills for the session. You and the agent decide what loads.

compile_skill("python") distils a domain's accumulated experience into a loadable SKILL.md — do this, watch out for that, never try X again because it cost you an afternoon. Load it at the start of Python work and the agent works your way from the first prompt.

// the flywheel
work → record_experience()compile_skill()SKILL.md → work

Every skill instructs the agent to keep recording lessons and dead ends while working under it. A richer pool compiles a better skill next time — and the knowledge watch flags fresh articles that contradict a compiled rule, so skills stay current.

Full design: the skill compiler

claude — compile_skill
claude> compile_skill("python")
→ 87 memories · 14 reinforced lessons · 3 dead ends
+ do pin deps with uv lock before builds
+ avoid gather() without return_exceptions
+ ref valkey-search HNSW tuning guide
~ watch new article may contradict rule #7
→ proposed diff — nothing written until you accept
claude> compile_skill("python", mode="write")
✓ SKILL.md committed · every rule cites its memories
06 How it compares

Most memory servers just store and retrieve

Claude Code's built-in memory — CLAUDE.md plus the newer auto-memory that writes markdown notes for itself — is still flat, machine-local files with keyword recall: no semantic search, no lifecycle, no contradiction handling. OmniMem goes quite a bit further.

Capability
Claude built-in
Typical MCP
<OmniMem>
Semantic vector search
Memory lifecycle states
Yes, 4 states
Abandoned approach warnings
Yes, graveyard
Experience scoring
Yes, effort 1-5
Compiled skills
Hand-written SKILL.md
Yes, from experience
Contradiction detection
Yes, 2-tier
Semantic deduplication
Partial
Yes, write + batch
Topic suppression
RSS knowledge ingestion
Yes, auto-summarised
Reinstate hints
Self-hosted / no SaaS
Local files
Varies
Yes, Docker
Multi-machine sync
Varies
Yes, via proxy
Web dashboard
Yes, htmx
Telemetry / Prometheus
Yes, /metrics
Auto-maintenance
Yes, on briefing
07 Architecture

Four containers. Nothing leaves your machine.

Local embeddings, self-hosted, Docker. Both the MCP server and web UI connect directly to Valkey and share the memory package.

AI agent
any machine · SSE/MCP
Browser
HTTP :8080
↓           ↓
MCP Server
Python fastmcp
remember · recall · deprioritise
record_experience · briefing · health
Web UI
Starlette · htmx · Jinja2
Dashboard · Search · Browse
Projects · Duplicates · Backups
↓           ↓
Valkey + search
idx:episodic
idx:project
idx:knowledge
RSS Worker
feedparser
APScheduler
Claude Haiku
// recall pipeline
query
abandoned fast-path (keyword scan)
embed query
vector search, top 20 / namespace
filter archived + deleted
filter suppressed topics
apply surface_score
apply recency decay (90d)
apply experience_weight
check reinstate eligibility
surface contradiction warnings
merge, re-rank, return top_k
log event + increment counters
08 Get started

Up and running in two minutes

01

Clone and configure

Pick a strong Valkey password. For RSS summaries and smarter contradiction detection, add your Anthropic API key too.

bash
# clone the repo
git clone https://code.squarecows.com/ric/omnimem.git
cd omnimem
cp .env.example .env
# edit .env: set VALKEY_PASSWORD and ANTHROPIC_API_KEY
02

Start the containers

Spins up four containers: Valkey with vector search, the MCP server, the RSS worker, and the web UI dashboard.

bash
docker compose up -d
# Web UI at http://localhost:8080
03

Connect Claude Code

Point Claude Code at OmniMem in your MCP config, then drop the included CLAUDE.md into your project.

~/.claude.json or .mcp.json
{
  "mcpServers": {
    "omnimem": {
      "type": "sse",
      "url": "http://localhost:8765/sse"
    }
  }
}
Pro tip

OmniMem's instructions are injected automatically when the MCP server connects. To customise how Claude uses OmniMem across all projects, add your own overrides to ~/.claude/CLAUDE.md.

View on Squarecows →