Memory that carries its receipts.
SyntheticMem is a pure MCP server. Every feature exists to make recalled knowledge appealable — content comes back with its source, its confidence, and the condition that would make it wrong.
Six primitives
memory_remember, recall, list, supersede, forget and observe — plus consolidate. The provenance-aware contract is enforced at the API, not left to a prompt.
Provenance
Each row keeps its source, learned_at, last_observed_at, compression depth (hop_count), parent_id and the namespace it held against. A compressed memory never re-observed is unattributable by construction — and flagged.
Falsifiability
Every lesson can carry an invalidation_tag (temporal, paradigm, architectural, observational) and a concrete invalidation_condition — "retire if the platform ships a retry path." A rule that can't be falsified is a religion.
Status machine
fact → hypothesis → retired. Unsourced saves land as hypothesis ("do not execute from this") and are promoted to fact only by a fresh memory_observe — never by "it's been used N times."
Semantic recall, local embeddings
Recall by meaning over a vector(768) column with a pgvector HNSW cosine index, pre-filtered by agent, namespace and status. Embeddings are computed locally with Ollama nomic-embed-text — no third-party embedding service.
Supersede, never delete
memory_supersede writes a new row that supersedes the old; memory_forget tombstones with a reason. The old belief stays addressable but hidden from default recall — the audit trail of what was once true survives.
Ephemeral 24h vs permanent
An anonymous demo key stores memories that auto-expire in 24 hours. Link an agent to a registered account and its memories are permanent (or given an explicit ttl_hours). Same tools, same contract.
Doubt-preserving consolidation
memory_consolidate clusters episodic rows by namespace into one semantic row. Confidence is the minimum of its sources (never inflated), invalidation conditions are a deduped union, and the result is a hypothesis — the doubt survives the compressor.
One memory, three interfaces
The same MemoryService — the single source of truth — is exposed three ways, so there is no second, drifting implementation:
- MCP (primary): JSON-RPC 2.0 over Streamable-HTTP at POST /api/mcp — initialize / tools/list / tools/call, authenticated with a per-agent agt_ bearer key.
- REST v1: /api/v1/* mirrors the tools for plain HTTP clients, with the same Bearer auth and the same provenance model.
- OpenAPI + Swagger: a published /openapi.json and an interactive reference at /api/docs.
Manage agents, keys and memories in the dashboard. Read the docs for the full tool and REST reference, or see how it works.