Memory for a personal AI agent, with every fact traceable to its source.
Evidence in, bounded context out. Nothing is silently overwritten.
MemoryGate is a self-hosted memory service for one personal agent. It receives evidence, keeps its lineage, turns lasting signals into structured memory, and returns a small context package the agent can use without touching a database.
It stores, retrieves and explains. It is not a chatbot and it never acts: the agent stays responsible for reasoning and action. Part of Conker, and usable on its own.
flowchart LR
Agent[Agent<br/>e.g. Conker's Pi] -->|evidence| MG[MemoryGate]
Agent -->|read key: what's relevant?| MG
MG --> PG[(PostgreSQL<br/>source of truth)]
MG --> QD[(Qdrant<br/>vector index)]
MG -->|text to vectors| EM[Embeddings]
classDef focus fill:#e36b2c,color:#fff,stroke:#b4521f
class MG focus
flowchart LR
E[Evidence<br/>immutable input] --> J[Processing job] --> A[Analysis] --> M[Memory · Entity · Episode]
M -. lineage .-> E
| Layer | What it holds |
|---|---|
| Evidence | Raw inputs from conversations, listeners, APIs or manual capture. Never edited. |
| Analysis | A recorded interpretation of one or more pieces of evidence. |
| Memory | Durable facts, phases, context and watch items, ready for retrieval. |
| Entity | People, projects, places, concepts, habits and objects. |
| Episode | A time-bounded event grouping related evidence. |
Every object can be opened in the dashboard with its history, links and supporting evidence.
PostgreSQL is the source of truth. Qdrant indexes meaning, using vectors from the Embeddings service; word matching runs alongside so exact names are never hidden by similarity ranking.
If Embeddings is unavailable, search falls back to word matching and says so. /health reports
degraded and names embeddings, and every result carries the retrieval_path that produced it.
Writes still succeed, and report when they could not be indexed.
Requires Docker with Compose.
docker network create conker_net # once; shared with the other Conker services
cp .env.example .env
echo "MEMORYGATE_ADMIN_KEY=$(openssl rand -base64 24)" >> .env
docker compose up -d --build| Dashboard | http://localhost:8021 |
| API | http://localhost:8020 |
Without an admin key the API refuses to start and names the fix. For meaning-based search, run
Embeddings on the same network and set EMBEDDINGS_KEY.
Then, in Settings, change the admin key and create one read key for your agent.
Give the agent a read key, never the admin key.
python services/cli/memorygate.py context "What should I remember about this project?"A read-only MCP configuration and agent skill live in integrations/. Raw events go in through a
listener with its own secret: POST /runtime/listeners/{source_key}.
- No admin key, no start. There is no open fallback.
- Read keys can retrieve context and nothing else. Listener secrets can only ingest.
- Keys are stored as PBKDF2 hashes; failed attempts are rate-limited.
- Destructive resets need the admin key and the phrase
RESET MEMORY, and take a backup first. - Models used by MemoryGate get no write, delete, shell or tool ability.
Keep the dashboard and API on a private network. Full model: security.
cd services/api
pip install -r requirements.txt -r requirements-dev.txt
python -m pytest testsThe suite needs no running services: it uses a real SQLite database and aims its health probes at a closed port, so the degraded paths run for real. More in development.
| Security model | Keys, CORS, destructive actions, bootstrap |
| Operations | Ingestion, backups, resets, limits |
| Dashboard | Every screen, with screenshots |
| AI runtime | Which models MemoryGate may use, and for what |
| Agent integration | Connecting an agent |
| Conversation memory | Admission, retries and forgetting for Pi |
| Development | Building, testing, layout |
| API (OpenAPI) | Full route reference |

