Secure · Auditable · Programmable Memory for AI Agents
Quick Start · Why Memoria? · Architecture · API Reference · Documentation
Memoria is a persistent memory layer for AI agents with Git-level version control. Every memory change is tracked, auditable, and reversible — snapshots, branches, merges, and time-travel rollback, all powered by MatrixOne's native Copy-on-Write engine.
%%{init: {'theme': 'base', 'themeVariables': {
'primaryColor': '#0A2540',
'primaryTextColor': '#E0F7FF',
'primaryBorderColor': '#00D4FF',
'lineColor': '#00A3CC',
'secondaryColor': '#1E3A5F',
'tertiaryColor': '#00D4FF'
}}}%%
graph TD
A[AI Agent]
-->|MCP Protocol| B[Memoria Core]
B --> C[Canonical Storage<br/>Single Source of Truth]
B --> D[Retrieval Strategy<br/>Pluggable Search]
C --> E[Git-for-Data Engine]
E --> F[MatrixOne]
subgraph "Security Layer"
G[Snapshot & Branch<br/>Zero-Copy Isolation]
H[Audit & Provenance<br/>Full Traceability]
I[Self-Governance<br/>Contradiction Detection]
end
B --> G
B --> H
B --> I
classDef core fill:#0A2540,stroke:#00D4FF,stroke-width:3px,color:#E0F7FF,rx:15,ry:15;
classDef storage fill:#1E3A5F,stroke:#00A3CC,stroke-width:2px,color:#E0F7FF;
classDef strategy fill:#1E3A5F,stroke:#00D4FF,stroke-width:2px,color:#E0F7FF;
classDef engine fill:#00A3CC,stroke:#00D4FF,color:#0A2540;
class A,B core;
class C,D storage;
class E engine;
class G,H,I strategy;
Core Capabilities:
- Cross-conversation memory — preferences, facts, and decisions persist across sessions
- Semantic search — retrieves memories by meaning, not just keywords
- Git for Data — zero-copy branching, instant snapshots, point-in-time rollback
- Audit trail — every memory mutation has a snapshot + provenance chain
- Self-maintaining — built-in governance detects contradictions, quarantines low-confidence memories
- Private by default — local embedding model option, no data leaves your machine
- Multi-instance ready — distributed lock + leader election, deploy multiple replicas behind a load balancer with zero external dependencies
Supported Agents: Kiro · Cursor · Claude Code · Any MCP-compatible agent
Storage Backend: MatrixOne — Distributed database with native vector indexing
| Skill | Domain | Description |
|---|---|---|
| Architecture | Codebase | Workspace layout, traits, tables, config, testing |
| API Reference | REST API | Endpoints, request/response formats, rate limits |
| Deployment | Operations | Docker Compose, K8s, env vars, multi-instance, security |
| Plugin Development | Plugins | Scaffold, test, sign, publish governance plugins |
| Setup | Installation | Install Memoria, configure MCP for AI tools |
| Release | CI/CD | Version bump, CI workflows, publish |
| Local Embedding | Embedding | Build from source, model selection, offline mode |
| Capability | Memoria | Letta / Mem0 / Traditional RAG |
|---|---|---|
| Git-level version control | Native zero-copy snapshots & branches | File-level or none |
| Isolated experimentation | One-click branch, merge after validation | Manual data duplication |
| Audit trail | Full snapshot + provenance on every mutation | Limited logging |
| Semantic retrieval | Vector + full-text hybrid search | Vector only |
| Multi-agent sharing | Shared trusted memory pool per user | Siloed per agent |
| Migration cost | Zero — all state in MatrixOne | Export/import required |
git clone https://github.com/matrixorigin/Memoria.git
cd Memoria
docker compose up -d
# Wait ~30-60s for first-time initializationDon't want Docker? Use MatrixOne Cloud (free tier).
Option A — Install script (detects OS/arch, verifies checksum):
curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bashOption B — Manual download from GitHub Releases:
# Linux (x86_64)
curl -LO https://github.com/matrixorigin/Memoria/releases/latest/download/memoria-x86_64-unknown-linux-gnu.tar.gz
tar xzf memoria-x86_64-unknown-linux-gnu.tar.gz
sudo mv memoria /usr/local/bin/
# macOS (Apple Silicon)
curl -LO https://github.com/matrixorigin/Memoria/releases/latest/download/memoria-aarch64-apple-darwin.tar.gz
tar xzf memoria-aarch64-apple-darwin.tar.gz
sudo mv memoria /usr/local/bin/cd your-project
# Interactive mode (recommended) — guides you through DB and embedding setup:
memoria init -i
# Or specify everything on the command line:
memoria init --tool kiro \
--embedding-provider openai \
--embedding-base-url https://api.siliconflow.cn/v1 \
--embedding-api-key sk-... \
--embedding-model BAAI/bge-m3 \
--embedding-dim 1024
# Or connect to an existing Memoria server (no DB needed):
memoria init --tool kiro --api-url "https://your-server:8100" --token "sk-your-key..."This creates:
- Kiro:
.kiro/settings/mcp.json+.kiro/steering/memory.md - Cursor:
.cursor/mcp.json+.cursor/rules/memory.mdc - Claude:
.mcp.json+CLAUDE.md
The generated mcp.json includes all environment variables (empty = not configured). Edit the file to fill in your values.
Restart your AI tool, then ask: "Do you have memory tools available?"
memoria status # check config files and rule versionsFor detailed setup options, see the Setup Guide.
A real setup conversation in Cursor — tell the agent what you want, it handles the rest:
You: I want to set up Memoria for persistent memory.
Cursor: Before I start, a few quick questions:
1. Which AI tool are you using? (Cursor, Kiro, Claude Code, or multiple?)
2. Do you have a MatrixOne database running? If not, I can start one with
Docker, or you can use MatrixOne Cloud (free tier, no Docker needed).
3. Do you have an embedding service? (OpenAI, SiliconFlow, Ollama, etc.)
If not, I can use a local model — requires building from source.
You: Cursor. No database yet. I have a SiliconFlow API key.
Cursor: Got it. I'll start MatrixOne with Docker first — running:
docker compose up -d
...
Cursor: Everything's configured. Try telling me a preference — like your test framework
or code style — and I'll remember it across all future conversations.
This guided flow is powered by the Setup Skill.
┌─────────────┐ MCP (stdio) ┌──────────────────────────────────────┐ SQL ┌────────────┐
│ Kiro / │ ◄─────────────────► │ Memoria MCP Server │ ◄──────────► │ MatrixOne │
│ Cursor / │ store / retrieve │ ├── Canonical Storage │ vector + │ Database │
│ Claude Code │ │ ├── Retrieval (vector / semantic) │ fulltext │ │
│ Any Agent │ │ └── Git-for-Data (snap/branch/merge)│ │ │
└─────────────┘ └──────────────────────────────────────┘ └────────────┘
Memoria exposes MCP tools that your AI tool calls automatically based on steering rules.
| Tool | Description |
|---|---|
memory_store |
Store a new memory |
memory_retrieve |
Retrieve relevant memories for a query (call at conversation start) |
memory_correct |
Update an existing memory with new content (by ID or semantic search) |
memory_purge |
Delete by ID, comma-separated batch IDs, or bulk-delete by topic keyword. Auto-creates safety snapshot for rollback |
memory_search |
Semantic search across all memories |
memory_profile |
Get user's memory-derived profile summary |
| Tool | Description |
|---|---|
memory_snapshot |
Create a named snapshot of current memory state |
memory_snapshots |
List snapshots with pagination (limit, offset). Shows total count |
memory_snapshot_delete |
Delete snapshots by name(s), prefix, or age. Supports batch deletion |
memory_rollback |
Restore memories to a previous snapshot |
| Tool | Description |
|---|---|
memory_branch |
Create a new branch for isolated experimentation (optionally from a snapshot or point-in-time) |
memory_branches |
List all branches |
memory_checkout |
Switch to a different branch (shows up to top_k memories after switching) |
memory_merge |
Merge a branch back into main |
memory_diff |
Preview what would change on merge (LCA-based diff with semantic classification) |
memory_branch_delete |
Delete a branch |
| Tool | Description |
|---|---|
memory_governance |
Quarantine low-confidence memories, clean stale data (1h cooldown) |
memory_consolidate |
Detect contradictions, fix orphaned graph nodes (30min cooldown) |
memory_reflect |
Synthesize high-level insights from memory clusters via LLM (2h cooldown) |
memory_extract_entities |
Extract named entities and build entity graph (proactive) |
memory_link_entities |
Write entity links from your own extraction results |
memory_rebuild_index |
Rebuild IVF vector index for a table |
For REST API details, see the API Reference.
| Type | What it stores | Example |
|---|---|---|
semantic |
Project facts, technical decisions | "This project uses Go 1.22 with modules" |
profile |
User/agent preferences | "Always use pytest, never unittest" |
procedural |
How-to knowledge, workflows | "To deploy: run make build then kubectl apply" |
working |
Temporary context for current task | "Currently refactoring the auth module" |
tool_result |
Results from tool executions | Cached command outputs |
episodic |
Session summaries (topic/action/outcome) | "Session Summary: Database optimization\n\nActions: Added indexes\n\nOutcome: 93% faster" |
Episodic Memory: High-level summaries of work sessions, generated via API. See Episodic Memory API for details.
You: "I prefer tabs over spaces, and always use black for formatting"
AI: → calls memory_store("User prefers tabs over spaces, uses black for formatting", type="profile")
... next conversation ...
You: "Format this Python file"
AI: → calls memory_retrieve("format python file")
← gets: [profile] User prefers tabs over spaces, uses black for formatting
→ formats with black, uses tabs
You: "Actually, I switched to ruff instead of black"
AI: → calls memory_correct(query="formatting tool", new_content="User uses ruff for formatting", reason="switched from black")
You: "Take a snapshot before we refactor the database layer"
AI: → calls memory_snapshot(name="before_db_refactor", description="pre-refactor state")
... refactoring goes wrong ...
You: "Roll back to before the refactor"
AI: → calls memory_rollback(name="before_db_refactor")
You: "Create a memory branch to evaluate switching from PostgreSQL to SQLite"
AI: → calls memory_branch(name="eval_sqlite")
→ calls memory_checkout(name="eval_sqlite")
You: "We're now using SQLite instead of PostgreSQL"
AI: → calls memory_store("Project uses SQLite for persistence", type="semantic")
(stored on eval_sqlite only — main is untouched)
You: "Merge it"
AI: → calls memory_diff(source="eval_sqlite") ← preview first
→ calls memory_merge(source="eval_sqlite", strategy="replace")
| Command | Description |
|---|---|
memoria init -i |
Interactive setup wizard — walks you through DB connection and embedding config |
memoria init --tool <name> |
Write MCP config + steering rules for specified AI tool (CLI flags) |
memoria status |
Show config files, rule versions, bundled version |
memoria update-rules |
Update steering rules to match current binary version |
memoria mcp --db-url <url> --user <id> |
Start MCP server in embedded mode (direct DB) |
memoria mcp --api-url <url> --token <key> |
Start MCP server in remote mode (proxy to REST API) |
memoria mcp --transport sse |
Start with SSE transport instead of stdio |
memoria serve |
Start REST API server |
memoria plugin init --dir <dir> --name <name> |
Scaffold a new governance plugin project |
memoria plugin publish --package-dir <dir> |
Publish plugin to shared repository |
memoria plugin dev-keygen --dir <dir> |
Generate ed25519 dev signing keypair |
memoria benchmark --api-url <url> --token <key> --dataset <name> |
Run benchmark against API |
memoria init generates the config once. To change settings afterwards, edit the config file directly:
- Kiro:
.kiro/settings/mcp.json - Cursor:
.cursor/mcp.json - Claude:
.mcp.json
Switch from local DB to remote server:
{
"mcpServers": {
"memoria": {
"command": "memoria",
"args": ["mcp", "--api-url", "https://your-server:8100", "--token", "sk-your-key..."]
}
}
}Change embedding provider (edit the env block):
{
"mcpServers": {
"memoria": {
"command": "memoria",
"args": ["mcp", "--db-url", "mysql+pymysql://root:111@localhost:6001/memoria", "--user", "alice"],
"env": {
"EMBEDDING_PROVIDER": "openai",
"EMBEDDING_BASE_URL": "https://api.siliconflow.cn/v1",
"EMBEDDING_API_KEY": "sk-...",
"EMBEDDING_MODEL": "BAAI/bge-m3",
"EMBEDDING_DIM": "1024"
}
}
}
}Re-run init to overwrite (use --force to also overwrite customized steering rules):
memoria init --tool kiro --api-url "https://new-server:8100" --token "sk-new-key..."
# steering rules are preserved unless --force is passedUpdate steering rules only (after upgrading Memoria):
memoria update-rules
# restart your AI toolRestart your AI tool after any config change.
cd your-project
memoria init --tool kiroOr manually create .kiro/settings/mcp.json:
{
"mcpServers": {
"memoria": {
"command": "memoria",
"args": ["mcp", "--db-url", "mysql+pymysql://root:111@localhost:6001/memoria", "--user", "alice"]
}
}
}The steering rule is bundled in the binary and written automatically by memoria init. Restart Kiro.
cd your-project
memoria init --tool cursorOr manually create .cursor/mcp.json (same structure as above). Restart Cursor.
cd your-project
memoria init --tool claudeOr manually edit claude_desktop_config.json (same structure). Restart Claude Desktop.
Memoria needs an embedding model to vectorize memories for semantic search.
| Provider | Quality | Privacy | Cost | First-use latency | Ongoing latency |
|---|---|---|---|---|---|
| Local (default) | Good | ✅ Data never leaves machine | Free | Model download on first query | Fast (in-process) |
| OpenAI / SiliconFlow | Better | API key required | None | Network round-trip | |
| Custom service | Varies | Depends on host | Self-hosted | None | Network round-trip |
Configure via environment variables in the MCP config env block:
"env": {
"EMBEDDING_PROVIDER": "openai",
"EMBEDDING_BASE_URL": "https://api.siliconflow.cn/v1",
"EMBEDDING_API_KEY": "sk-...",
"EMBEDDING_MODEL": "BAAI/bge-m3",
"EMBEDDING_DIM": "1024"
}Leave all empty to use local embedding (all-MiniLM-L6-v2, dim=384).
💡 Local Embedding Tips:
Local embedding requires building from source with --features local-embedding (pre-built binaries don't include it). See Local Embedding Guide for build instructions, supported models, and troubleshooting.
Integration quality depends on your AI agent's reasoning ability and steering rules. Out-of-the-box behavior may not be optimal.
If memory usage feels suboptimal, edit the steering rules in .kiro/steering/memory.md, .cursor/rules/memory.mdc, or CLAUDE.md to be more explicit. For example, if your agent forgets to retrieve memories at conversation start:
CRITICAL: At the start of EVERY conversation, call memory_retrieve with the user's first message.Memoria uses the Model Context Protocol (MCP) standard. Any MCP-compatible agent can integrate by pointing to the server:
{
"mcpServers": {
"memoria": {
"command": "memoria",
"args": ["mcp", "--db-url", "mysql+pymysql://root:111@localhost:6001/memoria", "--user", "alice"],
"env": {
"EMBEDDING_PROVIDER": "openai",
"EMBEDDING_API_KEY": "sk-...",
"EMBEDDING_MODEL": "BAAI/bge-m3",
"EMBEDDING_DIM": "1024"
}
}
}
}Or in remote mode (proxy to a deployed Memoria REST API):
{
"mcpServers": {
"memoria": {
"command": "memoria",
"args": ["mcp", "--api-url", "https://memoria-host:8100", "--token", "sk-your-key..."]
}
}
}docker ps | grep matrixone
# If not running:
docker start matrixoneThe pre-built binaries from GitHub Releases do not include local embedding. Use an OpenAI-compatible embedding service instead, or build from source with the feature enabled:
cd Memoria/memoria
cargo build --release -p memoria-cli --features local-embeddingExpected with local embedding — model loads into memory on first query (~3-5s). Use an embedding service to avoid this by setting EMBEDDING_PROVIDER=openai in the MCP config env block.
- Verify
memoriais in PATH:which memoria - Restart the AI tool after editing the MCP config
- Test the server directly:
memoria mcp --db-url "mysql+pymysql://root:111@localhost:6001/memoria"
These tools support a mode parameter:
auto(default): uses server-side LLM if configured, otherwise returns raw data for the AI agent to processcandidates: always returns raw data for the agent to process — no LLM neededinternal: forces server-side LLM processing — fails ifLLM_API_KEYis not set
In MCP mode, the calling agent is already an LLM, so auto (default) works out of the box — it falls back to candidates automatically. No extra LLM configuration needed.
POST /v1/sessions/{id}/summary requires LLM configuration. Set LLM_API_KEY in the MCP config env block (see above).
# Start MatrixOne + API
make up
# In another terminal, configure your AI tool for remote mode:
cd your-project
memoria init --tool kiro --api-url "http://localhost:8100" --token "test-master-key-for-docker-compose"
# Restart your AI toolOr use embedded mode (direct DB, no API):
cd your-project
memoria init --tool kiro --db-url "mysql+pymysql://root:111@localhost:6001/memoria"make test-unit # Unit tests (no DB)
make test # All tests (needs DB)
make test-e2e # E2E API tests (needs DB)make release VERSION=0.2.0 # Bump version, generate CHANGELOG, tag, push
# CI builds binaries + Docker image automatically
make release-rc VERSION=0.2.0-rc1 # Pre-releaseIf you're an AI agent helping a user set up Memoria, ask before acting:
- Which AI tool? Kiro / Cursor / Claude Desktop?
- MatrixOne database? Already have one → get URL. Local Docker →
docker compose up -d. MatrixOne Cloud → no Docker needed. - Embedding?
⚠️ Ask BEFORE installation. Once the MCP server starts, the embedding dimension is locked into the database schema. Already have a service (OpenAI/SiliconFlow/Ollama)? Use it. Otherwise local is fine. - Install: Download from GitHub Releases or build from source (
cargo build --release -p memoria-cli) - Configure: Run
memoria init --tool <name>in the user's project directory (see Quick Start for flags). It writes MCP config + steering rules. - Tell user to restart their AI tool
- Verify: Ask the AI tool to call
memory_retrieve("test")— should return "No relevant memories found"
Apache-2.0 © MatrixOrigin