agoya
README.md
# Oracle Memory
> The notebook your AI agents never lose. No database, no server farm — just JSON files and a really good search.
Every coding session, your agent learns something: a port number, a gotcha, a decision you made at 2 a.m. And every session, it forgets. **Oracle Memory** is the fix — a file-backed MCP memory server that lets agents *remember* across sessions and *find* what they wrote with hybrid keyword + semantic search.
```
remember ──▶ .oracle-memory/*.json ──▶ recall
(atomic writes) (BM25 + vectors + entity graph)
```
No Postgres. No Redis. No migrations. Delete a file and the memory is gone; back up a folder and it's safe. That's the whole storage engine.
---
## 60-second start
Needs **Node.js 24+**.
```bash
npm install -g oracle-memory
# Run it as an MCP server (stdio)
oracle-memory
# ...or scope it to a project
ORACLE_MEMORY_ROOT_DIR=/path/to/project oracle-memory
```
Wire it into Claude Code:
```bash
claude mcp add oracle-memory -- /path/to/oracle-memory/dist/index.js
```
(Codex works the same way — point its MCP config at the same path.)
---
## Four kinds of memory
Not everything deserves to be remembered forever. Pick the right shelf:
| Type | For | Lives |
|------|-----|-------|
| `fact` | Preferences, decisions, conventions | 🗿 Forever |
| `insight` | Lessons learned, gotchas, discoveries | 🗿 Forever |
| `chunk` | Conversation snapshots (pre-compact) | ⏳ Auto-expires (TTL) |
| `working` | Session scratchpad, temporary context | 🧹 Cleared between sessions |
---
## The tools
| Tool | What it does |
|------|--------------|
| `remember` | Save a fact / insight / chunk / working memory |
| `recall` | Search — BM25 + vector + entity-graph ranking, fused |
| `get_memory` | Fetch one memory by id + type |
| `update_memory` | Edit content / tags / importance / meta / TTL |
| `list_memories` | List with type / agent / tag / query filters |
| `forget` | Delete a memory for good |
| `clear_working` | Wipe an agent's scratchpad (or everyone's) |
| `consolidate` | Merge lookalike memories by tag overlap |
| `reflect` | Synthesize *new* higher-level insights from clusters of memories (LLM) |
| `list_conflicts` | Surface contradictions: flagged ties + quarantined memories |
| `verify_memory` | Resolve a contradiction — `keep` (supersede the loser) or `reject` |
| `get_sessions` | Who's currently connected |
| `get_stats` | Counts by type and agent |
And read-only resources for clients that prefer URIs:
| URI | Content |
|-----|---------|
| `oracle-memory://memories` | Everything |
| `oracle-memory://memories/{type}` | Filtered by type |
| `oracle-memory://stats` | Statistics |
| `oracle-memory://sessions` | Connected agents |
---
## The search is the magic
**BM25 keyword search** is built in — zero dependencies, fully offline, deterministic. Tokenize, drop stop words, rank. Fast and boring, in the best way.
**Vector semantic search** is the optional upgrade. Turn it on and every memory is also embedded with `Xenova/all-MiniLM-L6-v2` (384-dim). On `recall`, keyword hits and semantic hits are blended with **Reciprocal Rank Fusion (RRF)** — so "port config" finds the note that says "we run on 3000" even without a word in common.
The model (~15 MB) auto-downloads on first use and caches locally. Don't want it?
```bash
ORACLE_MEMORY_DISABLE_VECTORS=1 oracle-memory
```
---
## A day in the life
```bash
# Agent learns something
→ remember(agent="claude", type="fact", content="Project uses port 3000", tags=["config"])
# Weeks later, a different session, it just... knows
→ recall(query="port configuration")
← [{ entry: { content: "Project uses port 3000" }, score: 2.3, method: "bm25" }]
# Plans changed
→ update_memory(id="20260713-...", type="fact", { content: "Project uses port 4000" })
# How much does it know?
→ get_stats()
← { totalMemories: 42, byType: { fact: 20, insight: 10, chunk: 10, working: 2 } }
```
---
## Sharing memory across a team of agents (HTTP hub)
Run one memory server, connect many agents:
```bash
ORACLE_MEMORY_TRANSPORT=http ORACLE_MEMORY_PORT=8765 oracle-memory
```
```bash
claude mcp add --transport http oracle-memory http://localhost:8765/mcp
```
Lock it down with a bearer token before exposing it:
```bash
ORACLE_MEMORY_HTTP_TOKEN=your-secret ORACLE_MEMORY_TRANSPORT=http ORACLE_MEMORY_PORT=8765 oracle-memory
```
---
## Under the hood
```
<root>/.oracle-memory/
├── config.json # server config
├── facts/ # permanent knowledge
├── insights/ # lessons learned
├── chunks/ # conversation snapshots
├── working/ # scratchpads
├── graph/graph.json # entity relationship graph
└── vectors/ # embeddings (optional)
```
Every write is atomic (`.tmp` → rename), so a crash mid-write never corrupts your store.
### Environment
| Variable | Default | Description |
|----------|---------|-------------|
| `ORACLE_MEMORY_ROOT_DIR` | `cwd` | Root for the `.oracle-memory/` store |
| `ORACLE_MEMORY_DISABLE_VECTORS` | `false` | `1` to disable vector search |
| `ORACLE_MEMORY_TRANSPORT` | `stdio` | `stdio` or `http`/`streamable` |
| `ORACLE_MEMORY_HOST` | `0.0.0.0` | HTTP bind host |
| `ORACLE_MEMORY_PORT` | `8765` | HTTP port |
| `ORACLE_MEMORY_HTTP_TOKEN` | — | Bearer token for `/mcp` |
| `ORACLE_MEMORY_LOG_LEVEL` | `info` | Log verbosity |
> Migrating from an older setup? The legacy `AGOYA_*` env vars still work as fallbacks.
### Build
```bash
npm run build # TypeScript → dist/
npm run check # type-check only
npm run dev # run via tsx
npm start # run compiled
npm test # tests
```
---
## Benchmarks
A self-contained eval harness (no downloads) scores what the SOTA agent-memory papers care about: **retrieval quality** (recall@k, MRR) and **temporal correctness** — after a fact changes, does recall return the *new* value and suppress the superseded one?
```bash
npm run bench # BM25 + entity-graph + vectors
ORACLE_MEMORY_DISABLE_VECTORS=1 npm run bench # skip the embedding model
```
It writes `bench/results.svg`:

The bench exits non-zero if quality drops below its floors (recall@5 ≥ 75%, temporal = 100%), so it doubles as a CI regression gate.
---
## The rest of the family
Oracle Memory writes the `.oracle-memory/` format natively, so it slots right in with:
- 🧠 [Oracle](https://github.com/JonusNattapong/Oracle) — the AI coding consultant (skills + oracles)
- 📮 [Oracle Messages](https://github.com/JonusNattapong/oracle-messages) — multi-agent message bus
- 📖 [Oracle Skill](https://github.com/JonusNattapong/oracle-skill) — teaches any agent to use the stack
*One brain, one notebook, one group chat — no database in sight.*
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing