Memoria documentation

Long-term memory for AI agents — connect a client, call the API, and your agent remembers across sessions. Grounded, graph-based recall with automatic tiering and consolidation.

What is Memoria?

A deterministic long-term memory engine for AI agents — built to replace probabilistic vector guesswork and LLM write-wrappers.

Every memory is a typed, scored node connected to related memories by typed relationships (Supersedes, Causal, Semantic, DependsOn, Temporal). Unlike LLM memory wrappers that call a stochastic model on every write, Memoria's encode and recall paths are 100% deterministic: the same sequence of events produces the exact same state, the exact same Supersedes belief revisions, and the exact same recall trace in 12–17 ms with zero LLM tokens.

Memories live in retention tiers (Buffer → Episodic → Semantic → Core) and are automatically promoted, demoted, or forgotten based on importance and usage. Layered on top: 15-language multilingual reasoning, offline consolidation, reinforcement from feedback, safety filters (PII redaction + threat quarantine), and confidence scoring. Every operation is isolated by namespace.

Deterministic, not stochastic

Zero LLM calls on encode or recall. Supersedes belief revision, multi-session counting, and temporal queries execute deterministically in <15 ms.

Connected memory graph

Recall traverses causal, semantic, and temporal relationships to surface facts that flat vector similarity misses.

Auditable & tenant-isolated

Every recall emits a reproducible trace (/v1/trace/recent), and every query enforces strict organization and namespace isolation.

Three ways to use it: connect an MCP client (Claude Code, OpenCode, Cursor), call the HTTP API directly, or use an SDK. Start with the Quickstart.

Quickstart

From zero to your first recall in three steps.

1. Get an API key

Create an account (or log in). You'll get an isolated namespace and your first key — it starts with mem_dev_ and is shown once. Generate more anytime from your account.

2. Connect your agent (MCP)

Add the Memoria MCP server to Claude Code with one command:

claude mcp add -s user --transport http memoria https://memoria.kolivri.com/v1/mcp \
  --header "Authorization: Bearer mem_dev_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

…or paste this into your MCP client config (Cursor, Claude Desktop, etc.):

{
  "mcpServers": {
    "memoria": {
      "type": "http",
      "url": "https://memoria.kolivri.com/v1/mcp",
      "headers": { "Authorization": "Bearer mem_dev_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
    }
  }
}

3. Remember & recall

Your agent can now store and retrieve memories in your namespace. Or hit the HTTP API directly:

# store a memory
curl -X POST https://memoria.kolivri.com/v1/memories \
  -H "Authorization: Bearer $MEMORIA_KEY" -H "Content-Type: application/json" \
  -d '{"content":"We deploy on Fridays after 2pm","type":"Episodic","namespace":"my-project"}'

# recall what you know
curl -X POST https://memoria.kolivri.com/v1/memories/recall \
  -H "Authorization: Bearer $MEMORIA_KEY" -H "Content-Type: application/json" \
  -d '{"query":"when do we deploy?","namespace":"my-project"}'

Organization isolation is handled automatically behind the scenes from your API key — pass any project or workspace name (e.g. my-project or default) in the namespace field.

Core concepts

The concepts you work with when storing and recalling memories.

Memory tiers

Every memory has a retention tier. Migration between tiers is automatic, driven by salience and access patterns.

TierRetentionLifecycleNotes
BufferShort-termPromotes on repeated access or high salienceAutomatically expired when unused.
EpisodicMedium-termPromotes with sustained usage across sessionsCaptures session events and task history.
SemanticLong-termPromotes when confirmed as durable knowledgeDistilled project facts and conventions.
CorePermanentPinned or created as core rulesNever decays or expires.

Memory types

The type you assign at encode time. Over the HTTP API and TypeScript SDK these are PascalCase (Episodic); over MCP, the Python SDK, and the CLI they're lowercase (episodic).

TypeMeaning
BufferShort-lived scratch memory awaiting promotion.
EpisodicAn event or experience carrying temporal context.
SemanticDistilled factual knowledge.
CoreImmutable foundational knowledge.
ProceduralA learned action sequence or workflow.
ProspectiveA future-oriented intention or reminder.

Relationship edge types

Memories are connected by typed relationships so recall can follow causal chains, dependency trees, and belief revisions.

Edge typeMeaning
CausalOne memory caused or led to another.
DerivedFromSource was derived from the target — a provenance trail.
DependsOnSource requires the target to hold.
AssumesSource depends on the truth of a target assumption.
SupersedesSource replaces the target; outdated memories are automatically suppressed.
EvidenceSource provides evidence supporting the target.
SemanticShared meaning or topic, linked automatically at encode time.
CoRetrievalFrequently retrieved together and reinforced on co-access.
SchemaLinked through a shared category schema.
ContainsStructural containment (project → dir → file → definition).
PredictsSource predicts the target will be needed.
TemporalSequential proximity in time, linked automatically.
ContradictsMarks conflicting statements so stale or contradictory state is surfaced.

Deterministic graph recall

Recall matches your query against your isolated namespace and traverses connected relationships (Causal, DependsOn, Semantic, Supersedes) to surface relevant context — even when an important decision does not share exact keywords with the prompt. Every traversal strictly enforces your organization namespace boundary.

Ranking & belief revision

Candidates are ranked deterministically using relevance, salience, recency, retention tier, and historical utility. When a newer memory Supersedes an older one, the outdated fact is automatically suppressed so your agent always receives current state.

Salience

Salience is a memory's importance (0–1). An explicit value you pass always wins; otherwise Memoria assigns it automatically based on novelty and high-consequence signals. Salience guides ranking and retention tier promotion.

Consolidation

Consolidation merges near-duplicate episodic captures into clean Semantic knowledge linked by Supersedes, reinforces co-accessed memories, groups related session events, and flags contradictions.

Feedback & reinforcement

Calling /v1/feedback or the feedback MCP tool marks a memory as useful or unhelpful, immediately adjusting its future ranking priority without deleting history.

Safety: PII & quarantine

Before storage, Memoria can redact sensitive identifiers (emails, phone numbers, API keys, payment cards) and quarantine suspected prompt-injection payloads so poisoned inputs do not corrupt agent context.

Confidence & diagnostics

Every recall evaluates result confidence and emits an auditable trace (GET /v1/trace/recent) so you can inspect why specific memories were returned.

Authentication

One key per request, scoped to your namespace.

API keys

Authenticate every request with your key as a Bearer token:

Authorization: Bearer mem_dev_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Keys look like mem_dev_ followed by 43 URL-safe characters. The raw key is shown once at creation and never stored — only a SHA-256 hash is kept, so if you lose a key you mint a new one. The token is opaque: it carries no embedded namespace; your scope is looked up server-side.

Namespaces & isolation

Every API key is automatically scoped to your organization behind the scenes — you never pass an org: identifier. The namespace field in API and MCP calls is purely for your own project, repository, or agent wing name (e.g. my-project, backend, or default). One organization's data can never surface in another's query.

Rotating & revoking keys

Mint additional keys and revoke any key instantly from your account. Revocation takes effect on the very next request (nothing is cached). You can only see and revoke keys under your own account.

Rate limits & quota

Requests are rate-limited per key (a token bucket). Exceed it and you get 429 Too Many Requests with a Retry-After header and a JSON body {code:"RATE_LIMIT_EXCEEDED", status:429, message}. Each organization also has a rolling usage quota; once it's exhausted, requests return 402 Payment Required until the window advances. The exact throughput and quota scale with your plan — check your account.

Connect via MCP

The Model Context Protocol is the fastest path — your agent gets memory tools automatically.

Add Memoria to Claude Code:

claude mcp add -s user --transport http memoria https://memoria.kolivri.com/v1/mcp \
  --header "Authorization: Bearer mem_dev_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Or configure any MCP client (Cursor, Claude Desktop, VS Code) with:

{
  "mcpServers": {
    "memoria": {
      "type": "http",
      "url": "https://memoria.kolivri.com/v1/mcp",
      "headers": { "Authorization": "Bearer mem_dev_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
    }
  }
}

The connection speaks JSON-RPC 2.0 over streamable HTTP (protocol 2024-11-05). Namespace is chosen per call via the namespace argument (or the x-memoria-namespace header default).

Memory tools

ToolParamsDoes
recall_memoriesquery, namespace?, token_budget?, mode?Retrieve relevant memories with metacognition.
build_contextquery, namespace?, token_budget?, mode?Assemble a token-budgeted context string for a query.
encode_memorycontent, type?, namespace?, salience?, context?Store a memory (type: episodic·semantic·buffer·core).
forget_memoryidDelete a memory by UUID.
feedbackid, usefulMark a recalled memory useful / not useful.
consolidatenamespaceMerge duplicates, detect patterns & edges.
statsnamespacePer-namespace memory count + tier breakdown.
health—Engine-wide health across namespaces.

Code-intelligence tools

Index a repository into a code/<project> namespace and these become available:

ToolDoes
search_codeSemantic search over indexed code definitions.
explain_codeWhat a symbol is, who calls it, its tests.
find_referencesEvery reference to a symbol (graded).
find_fileLocate a file/dir by path substring.
impactTransitive blast radius of changing a symbol.
call_treeCaller / callee tree for a symbol.
dead_code · test_gapsUncalled definitions · definitions with no test.
rename · diff_riskRename worklist · callers at risk for changed symbols.
implementorsTypes implementing a trait/interface.
explain_diff · explain_errorAnalyse a unified diff · an error/stack trace.
navigate · get_hierarchyWalk the containment map · a node’s full vertical context.

Calling a tool directly

The same tools are reachable over plain HTTP JSON-RPC at POST /v1/mcp:

curl -X POST https://memoria.kolivri.com/v1/mcp \
  -H "Authorization: Bearer $MEMORIA_KEY" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"recall_memories",
                 "arguments":{"query":"auth flow","namespace":"code/myapp"}}}'

Successful results come back as {content:[{type:"text", text:<json>}]}. Call tools/list to see everything the server advertises.

HTTP API

Everything the agents do, over plain REST. Base URL https://memoria.kolivri.com, all routes under /v1, Bearer auth.

Memory

POST/v1/memories
Encode one memory. Runs quarantine + dedup; returns its tier and salience.
Body{ content, type, namespace, salience?, context?, links? }
Returns201 { id, created_at, salience, tier, quarantined, is_duplicate, duplicate_of? }
curl -X POST https://memoria.kolivri.com/v1/memories \
  -H "Authorization: Bearer $MEMORIA_KEY" -H "Content-Type: application/json" \
  -d '{"content":"user prefers dark mode","type":"Episodic","namespace":"my-project","salience":0.8,"context":{"user_id":"john-123"}}'
POST/v1/memories/recall
Recall memories for a query through the full pipeline; returns scored results + metacognition.
Body{ query, namespace, token_budget?=4096, min_salience?=0, context?, mode? }
Returns200 { results:[{ memory, score }], total_candidates, latency_ms, metacognition? }
curl -X POST https://memoria.kolivri.com/v1/memories/recall \
  -H "Authorization: Bearer $MEMORIA_KEY" -H "Content-Type: application/json" \
  -d '{"query":"authentication tokens","namespace":"my-project","token_budget":4096}'
POST/v1/memories/context
Build a single token-budgeted context string from recalled memories.
Body{ query, namespace, token_budget?=4096, format?=Structured (Structured|Narrative|Raw), context?, mode? }
Returns200 { context, memories_used }
POST/v1/memories/recall/enhanced
Recall with diversity filtering, recall tracing, and confidence metadata.
Body{ query, namespace, token_budget?, diversity?=0.7, min_salience?, mode? }
Returns200 { results, total_candidates, latency_ms, cache_hit, trace_id?, metacognition? }
DELETE/v1/memories/:id
Forget a memory by UUID.
Body(none)
Returns200 { deleted }
GET/v1/memories/:id/neighbors
List a memory’s outgoing edges.
Body(none)
Returns200 { edges:[{ target_id, edge_type, weight }] }

Batch & bulk

POST/v1/memories/batch
Encode up to 1000 memories at once (plain or gzip+base64 body; ≤64 MiB decompressed).
Body{ memories:[{ content, type?, salience?, context?, namespace }] }
Returns201 { ids, encoded, failed, compressed_size, raw_size }
POST/v1/memories/recall/batch
Run several recall queries in one request.
Body{ queries:[{ query, namespace, token_budget? }] }
Returns200 { results: MemoryResult[][] }
DELETE/v1/memories/by-context
GDPR-style bulk delete: forget every memory whose context key equals a value. (POST /v1/memories/by-context/delete is an alias.)
Body{ namespace, context_key, context_value }
Returns200 { deleted }

Learning

POST/v1/consolidate
Run offline consolidation over a namespace.
Body{ namespace }
Returns200 { patterns_found, edges_created, memories_created, contradictions }
POST/v1/feedback
Submit retrieval feedback for a memory; drives reward + dampening.
Body{ memory_id? | recall_id?, useful?, score? }
Returns200 { updated }

Prospective memory (intentions)

POST/v1/intentions
Create an intention with a context / time / event trigger.
Body{ trigger_type, trigger_data, action, salience, expires_at?, namespace }
Returns201 { id }
GET/v1/intentions?namespace=NS
List active (unfired, unexpired) intentions.
Body(query)
Returns200 { intentions:[{ id, trigger_type, action, salience, expires_at?, created_at, namespace }] }
DELETE/v1/intentions/:id
Delete an intention.
Body(none)
Returns200 { deleted }

Introspection

GET/v1/health
Engine health / liveness: counts and tier distribution.
Body(none)
Returns200 { memory_count, edge_count, tier_distribution, namespace_count }
GET/v1/stats?namespace=NS
Per-namespace aggregate statistics.
Body(query)
Returns200 (MemoryStats)
GET/v1/meta/knowledge-map?topic=T&namespace=NS
Metamemory confidence/gap entry for a topic.
Body(query)
Returns200 (KnowledgeMapEntry)
GET/v1/meta/contradictions?namespace=NS
List detected contradictions in a namespace.
Body(query)
Returns200 { contradictions:[…] }
GET/v1/graph/dot?namespace=NS&max_nodes=50
Export the namespace graph as Graphviz DOT text.
Body(query)
Returns200 text/plain (DOT)
GET/v1/trace/:recall_id
Fetch a stored recall trace (from enhanced recall).
Body(none)
Returns200 (RecallTrace)
GET/v1/events/stream
Server-Sent Events stream of lifecycle events (30s keep-alive).
Body(none)
Returnstext/event-stream
GET/v1/events?since=RFC3339
Poll recent lifecycle events after a timestamp.
Body(query)
Returns200 [{ event_type, data, timestamp, id }]

An interactive OpenAPI spec is served at /v1/openapi.json (Swagger UI at /v1/docs). Auth/rate-limit errors return {code, status, message}; most other errors are a bare status code.

Code intelligence

Index a repository into a code/<project> namespace and Memoria becomes a queryable map of it — definitions, references, call graphs, blast radius.

Method · PathPurpose
POST /v1/code/searchSemantic search over indexed definitions (optional type filter).
POST /v1/code/explainWhat a symbol is, who uses it (live scan), and its tests.
POST /v1/code/referencesEvery reference to a symbol — call / definition / mention, graded.
POST /v1/code/findFind files/dirs whose path matches a name, shallowest first.
POST /v1/code/impactBlast radius: transitive reverse-call walk of what could break.
POST /v1/code/call-treeNested caller (in) or callee (out) tree.
POST /v1/code/dead-codeDefinitions with no in-namespace caller (removal candidates).
POST /v1/code/test-gapsNon-test definitions with no direct test caller.
POST /v1/code/renameReviewed line-level edit worklist for a rename (not an auto-patcher).
POST /v1/code/diff-riskFor a set of changed symbols, their direct callers at risk.
POST /v1/code/implementorsTypes whose impl Trait for Type names a symbol (Rust today).
POST /v1/code/diff · /errorNatural-language analysis of a unified diff · an error/stack trace.
POST /v1/code/build-edgesMaterialise Contains + DependsOn edges after indexing (idempotent).

Example: find everything a change would affect

curl -X POST https://memoria.kolivri.com/v1/code/impact \
  -H "Authorization: Bearer $MEMORIA_KEY" -H "Content-Type: application/json" \
  -d '{"namespace":"code/myapp","symbol":"calc_total","max_depth":5,"limit":200}'
# -> { symbol, affected:[{ qualified_name, file, line, depth, min_confidence }], total, truncated }

All code tools are also exposed as MCP tools (see Connect via MCP) and in the TypeScript SDK under memoria.code.*. Findings are graded (exact / heuristic / ambiguous) with confidence scores — treat rename and dead-code output as a reviewed worklist, not an automatic edit.

SDKs

TypeScript / JavaScript

A thin, zero-dependency fetch client for the HTTP API (Node 18+ or the browser). Enum values are PascalCase (Episodic).

import { Memoria } from "@memoria/sdk";

const memoria = new Memoria({
  baseUrl: "https://memoria.kolivri.com",
  apiKey: process.env.MEMORIA_KEY,   // -> Authorization: Bearer <key>
  namespace: "my-project",           // project / workspace name (org scoping is automatic)
});

const { id, tier } = await memoria.encode({ content: "Deployed v2 to prod", type: "Episodic" });
const hits = await memoria.recall({ query: "deployment", token_budget: 2048 });
const { context } = await memoria.buildContext("deployment", 4096);

// code intelligence over an indexed namespace:
const refs = await memoria.code.findReferences("calc_total");
MethodEndpoint
encode(req)POST /v1/memories
recall(req)POST /v1/memories/recall
buildContext(query, budget?, format?)POST /v1/memories/context
forget(id) · neighbors(id)DELETE · GET /v1/memories/:id[…]
encodeBatch(…) · recallBatch(…)POST /v1/memories/batch[…]
consolidate(ns?) · feedback(req)POST /v1/consolidate · /v1/feedback
deleteByContext(req) · health()DELETE /v1/memories/by-context · GET /v1/health
navigate(…) · hierarchy(node)POST /v1/navigate · /v1/hierarchy
code.search / explain / findReferences / impact / callTree / …POST /v1/code/*

Non-2xx responses throw MemoriaError { message, status, body }.

Python

A native (PyO3) module that links the engine in-process — embedded, no server or HTTP. Build with maturin develop. Enum-like strings are lowercase (episodic). Surface: encode · recall · build_context · forget · health.

from memoria import Memoria

m = Memoria()  # in-process; wraps the engine directly

mid = m.encode("Deployed v2 to prod", "episodic", "myapp")
out = m.recall("deployment", "myapp", token_budget=2048)
for r in out["results"]:
    print(r["score"], r["content"])

print(m.build_context("deployment", "myapp", 4096)["context"])

The Python SDK is for embedding the engine locally. For the hosted cloud service, use MCP, the HTTP API, or the TypeScript SDK.

CLI

The memoria binary runs against a local SQLite database (default ~/.memoria/memoria.db). Global flags: --db PATH, --format text|json, --verbose.

CommandDoes
memoria healthGraph stats: memory/edge counts, tier distribution.
memoria encode --namespace NS --content T --type episodicEncode a memory; prints its id.
memoria recall --namespace NS --query T [--budget 4096]Recall ranked results for a query.
memoria search --namespace NS --query TBM25 lexical search (top 20).
memoria forget --id UUIDDelete a memory by UUID.
memoria stats --namespace NSPer-namespace stats + health assessment.
memoria consolidate --namespace NSRun offline consolidation.
memoria migrate --namespace NSRun tier promotion/demotion/GC.
memoria contradictions --namespace NSDetect contradictory memory pairs.
memoria meta --namespace NS --topic TMetamemory knowledge-map for a topic.
memoria export --namespace NSDump all memories in a namespace as JSON.
memoria import json|csv --file F --namespace NSImport memories from a file.
memoria graph dot|ascii …Export the graph (Graphviz DOT / ASCII neighborhood).
memoria backup|restore --file FChecksummed JSON backup / restore.
memoria trace --lastShow the most recent recall trace.
memoria pii-check --content TScan text for PII.

--db must come before the subcommand: memoria --db /path.db health. Memory types accept lowercase values.

FAQ & limits

Is my data isolated from other customers?

Yes. Your key resolves to your own organization and namespace, and every read, write, and graph traversal enforces strict tenant boundaries — one organization’s data can never surface in another’s query.

What happens when I lose a key?

You can’t recover it — only a hash is stored. Mint a new key from your account and revoke the old one. Revocation is effective on the next request.

Do I have to manage tiers or forgetting myself?

No. Promotion, demotion, and garbage-collection between Buffer → Episodic → Semantic → Core happen automatically from salience and access patterns. Pin a memory or set it to Core to keep it forever.

How big can a batch be?

Up to 1000 memories per /v1/memories/batch call; the decompressed payload must be ≤64 MiB. For larger loads, send multiple batches.

What are the rate limits?

Requests are rate-limited per key (429 with a Retry-After header when you exceed it), and each org has a rolling usage quota (402 when it’s exhausted, until the window advances). The exact numbers scale with your plan — see your account.

Which memory-type casing do I use?

PascalCase (Episodic) over the HTTP API and TypeScript SDK; lowercase (episodic) over MCP, the Python SDK, and the CLI.

How do I use code intelligence?

Index a repo into a code/<project> namespace, then call the /v1/code/* endpoints or the corresponding MCP tools. Findings are graded by confidence — treat rename/dead-code as a reviewed worklist.

Still stuck? Your account has your API keys and Memory Explorer, and the Quickstart gets you connected in a minute.