Give your AI agent a persistent, queryable memory β powered by a local knowledge graph.
AI agents forget everything between sessions. Context windows overflow. MEMORY.md files become unstructured dumps. RAG retrieval misses relationships.
agent-memory-graph builds a structured knowledge graph from your conversations β automatically. Every person, project, tool, and relationship is extracted, stored locally in SQLite, and queryable with natural language.
You: "I just met Viktor, the CTO of Nexus Labs. They're building SkyNet-X using Rust."
β Graph auto-extracts:
Viktor (Person) ββ[CTO_OF]βββ Nexus Labs (Company)
Nexus Labs ββ[BUILDS]βββ SkyNet-X (Project)
SkyNet-X ββ[USES]βββ Rust (Language)
You: "Who works at Nexus Labs?"
β "People at Nexus Labs: Viktor"
You: "How is Viktor connected to Rust?"
β "Viktor β[CTO_OF]β Nexus Labs β[BUILDS]β SkyNet-X β[USES]β Rust"
| Feature | Description |
|---|---|
| π§ Auto-extraction | Hybrid: local rule-based + LLM fallback for complex text |
| π Zero-API mode | Works fully offline β local extraction + local embeddings |
| π£οΈ Natural language queries | Ask questions like "Who works at X?" or "What does Y use?" |
| π Path finding | Discover hidden connections between entities (BFS, up to 5 hops) |
| π Semantic search | Local n-gram embeddings (256d) β no OpenAI key needed |
| π¦ Single SQLite file | Zero external deps, fully portable, survives restarts |
| π Domain-agnostic | Software, crypto, research, CRM, notes β anything |
| β‘ Zero-config | Works out of the box with zero API keys |
| π OpenClaw plugin | Auto-ingests every conversation, registers 11 tools |
| π Temporal facts | Graphiti-inspired: facts have valid_from/valid_until, never deleted |
| π Confidence decay | Unused entities/relations lose confidence over time |
| π§Ή Relation normalization | Synonyms merged, vague relations rejected automatically |
| π₯οΈ MCP server | Compatible with Claude Code, Cursor, Gemini CLI |
| π Export | Mermaid, DOT, JSON, CSV for visualization |
- Node.js 18β22 (recommended) β
better-sqlite3has prebuilt binaries - Node.js 24 β works but requires build tools (
gcc,make,python3) for native compilation - No API key required β works fully offline with local extraction + local embeddings
- Optional: Any OpenAI-compatible LLM β for higher-quality extraction in hybrid/llm mode
npm install agent-memory-graphimport { MemoryGraph } from 'agent-memory-graph';
const graph = new MemoryGraph();
// Ingest β entities and relationships are auto-extracted
await graph.ingest(
"Alice is the CTO of TechCorp. She leads the Platform team " +
"and uses Kubernetes, Go, and PostgreSQL."
);
// Query with natural language
await graph.ask("What does Alice use?");
// β "Alice: USES β Kubernetes, Go, PostgreSQL"
await graph.ask("Who works at TechCorp?");
// β "People at TechCorp: Alice"
// Find hidden connections
graph.findPath("Bob", "PostgreSQL");
// β Bob β[MEMBER_OF]β Platform team β[LED_BY]β Alice β[USES]β PostgreSQL
graph.close();# Ingest from text
memory-graph ingest "Started learning Rust for the new backend service"
# Ask questions
memory-graph ask "What am I learning?"
# β "Found: Rust (Language)"
# Search entities
memory-graph search "Rust"
# Find paths
memory-graph path "Alice" "PostgreSQL"
# Visualize
memory-graph visualize --format mermaid
# Stats
memory-graph stats
# β Entities: 42 | Relationships: 67 | Types: Person, Tool, Project...The killer feature: install as an OpenClaw plugin and your agent automatically remembers everything.
openclaw plugins install agent-memory-graph --dangerously-force-unsafe-install
openclaw gateway restart
β οΈ The--dangerously-force-unsafe-installflag is required because the plugin reads environment variables (API keys) and makes network calls (to your LLM provider). This is expected behavior for LLM-powered extraction.
- Every message (>20 chars) is auto-ingested into the knowledge graph
- 11 tools are registered for the agent to call:
memory_graph_ingestβ manually add knowledgememory_graph_queryβ natural language questionsmemory_graph_searchβ keyword searchmemory_graph_pathβ find connections between entitiesmemory_graph_statsβ graph statisticsmemory_graph_temporalβ query facts at a point in timememory_graph_supersedeβ update facts (old β new)memory_graph_decayβ apply confidence decaymemory_graph_embedβ generate embeddings for semantic searchmemory_graph_semantic_searchβ find similar entities by meaningmemory_graph_dedup_relationsβ clean up duplicate/vague relations
- Data persists in
~/.openclaw/data/memory-graph.dbβ survives/new,/reset, and restarts
[19:02] You: Hey, I just met Viktor who's the CTO of Nexus Labs.
They're building SkyNet-X using Rust and ROS2.
ββ memory-graph hook ββββββββββββββββββββββββββββββ
β β Auto-ingested: 4 entities, 5 relationships β
β Viktor (Person), Nexus Labs (Company), β
β SkyNet-X (Project), Rust (Language) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
[19:05] You: Who works at Nexus Labs?
Agent calls: memory_graph_query("Who works at Nexus Labs?")
β "People at Nexus Labs: Viktor"
[19:06] You: How is Viktor connected to Rust?
Agent calls: memory_graph_path("Viktor", "Rust")
β "Viktor β[CTO_OF]β Nexus Labs β[BUILDS]β SkyNet-X β[USES]β Rust"
{
"plugins": {
"entries": {
"memory-graph": {
"enabled": true,
"config": {
"autoIngest": true,
"extractionModel": "gpt-4o-mini",
"extractionMode": "hybrid",
"dbPath": "~/.openclaw/data/memory-graph.db",
"maxHops": 5,
"minConfidence": 0.7
}
}
}
}
}Extraction modes:
| Mode | API Cost | Quality | When to use |
|---|---|---|---|
"local" |
Zero | Good for simple text | No API key, offline, cost-sensitive |
"hybrid" (default) |
~70-80% less | Best balance | Most users β local first, LLM for complex text |
"llm" |
Full | Highest | When accuracy is critical and you have API budget |
Set autoIngest: false to disable auto-ingestion and only use manual tool calls.
The NL query engine understands 12+ question patterns:
| Question | What it does |
|---|---|
| "What is Alice working on?" | Find outgoing relationships |
| "Who works at TechCorp?" | Find people connected to entity |
| "Where did Bob work before?" | Find PREVIOUSLY_WORKED_AT relations |
| "What does the team use?" | Find USES relationships |
| "What is Alice's role?" | Look up role property/relation |
| "List all people" | Filter by type (normalizes "people" β "Person") |
| "List all companies" | Type normalization works for all types |
| "How is A connected to B?" | BFS path finding |
| "Who suggested X?" | Verb-to-relation matching |
| "What tools are mentioned?" | Type-based listing |
graph LR
classDef person fill:#3b82f6,stroke:#1d4ed8,color:#fff
classDef company fill:#f97316,stroke:#c2410c,color:#fff
classDef project fill:#8b5cf6,stroke:#6d28d9,color:#fff
classDef tool fill:#10b981,stroke:#047857,color:#fff
Alice[Alice - CTO]:::person
Bob[Bob - Engineer]:::person
TechCorp[TechCorp]:::company
Platform[Platform Team]:::project
K8s[Kubernetes]:::tool
Go[Go]:::tool
PG[PostgreSQL]:::tool
Alice -->|CTO_OF| TechCorp
Alice -->|LEADS| Platform
Alice -->|USES| K8s
Alice -->|USES| Go
Alice -->|USES| PG
Bob -->|MEMBER_OF| Platform
Bob -->|WORKS_AT| TechCorp
No API key? No problem. The plugin works completely offline:
# No environment variables needed!
openclaw plugins install agent-memory-graph --dangerously-force-unsafe-install
openclaw gateway restart
# That's it. Everything works.What works offline:
- β Entity extraction (rule-based pattern matching)
- β Relationship detection (grammar patterns: "X works at Y", "X built Y", etc.)
- β Semantic search (local n-gram embeddings, 256 dimensions)
- β All graph operations (search, path, temporal, supersede, decay, dedup)
- β Auto-ingestion from conversations
What needs an API (optional):
- LLM extraction for complex/ambiguous text (hybrid mode fallback)
- Higher-dimensional embeddings (text-embedding-3-small via OpenAI)
The rule-based extractor uses:
- Named Entity Recognition β capitalized words, type indicator patterns ("CEO of X", "built Y")
- Relationship patterns β 11 grammar templates (WORKS_AT, BUILDS, USES, LOCATED_IN, SUPPORTS, etc.)
- Relation normalization β synonyms merged (CREATED/DEVELOPED/AUTHORED β BUILDS)
- Vague relation rejection β RELATED_TO, ASSOCIATED_WITH, etc. are filtered out
- Confidence scoring β local results get 0.5-0.7 confidence (vs 0.8-1.0 for LLM)
Instead of calling OpenAI's embedding API, we generate 256-dimensional vectors locally:
- Character trigrams β "hello" β ["hel", "ell", "llo"]
- Word unigrams + bigrams β "hello world" β ["hello", "world", "hello world"]
- FNV-1a hashing β each n-gram hashed to a vector position
- TF normalization β frequency-weighted, L2-normalized output
- Cosine similarity β compare vectors in JS (no pgvector needed)
Quality benchmarks:
- Bitcoin β Ethereum: 0.80 similarity (related concepts)
- Bitcoin β Apple fruit: 0.13 similarity (unrelated)
- "AI agent memory" β finds "agent memory" entity at 67.5% match
Works with any OpenAI-compatible API β OpenAI, Anthropic (via proxy), Ollama, LiteLLM, vLLM, 9router, etc.
| Variable | Description | Default |
|---|---|---|
OPENAI_API_KEY |
API key | sk-local |
OPENAI_BASE_URL |
API base URL | http://127.0.0.1:20128/v1 |
MEMORY_GRAPH_API_KEY |
Override API key | β |
MEMORY_GRAPH_BASE_URL |
Override base URL | β |
MEMORY_GRAPH_MODEL |
Override model | gpt-4o-mini |
Examples:
# OpenAI
export OPENAI_API_KEY="sk-..."
# Anthropic via LiteLLM/9router
export OPENAI_BASE_URL="http://127.0.0.1:4000/v1"
export MEMORY_GRAPH_MODEL="claude-3-5-haiku-20241022"
# Ollama (free, local)
export OPENAI_BASE_URL="http://localhost:11434/v1"
export MEMORY_GRAPH_MODEL="llama3.1"Improve extraction accuracy for your specific domain:
{
"domains": [{
"name": "software",
"entityHints": ["Person", "Repository", "Language", "Framework", "Service"],
"relationHints": ["MAINTAINS", "USES", "DEPENDS_ON", "DEPLOYS_TO"]
}]
}βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MemoryGraph API β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Ingest β Query β Search β Temporal β Export β
ββββββββββββΌββββββββββΌβββββββββββΌβββββββββββββΌββββββββββ€
β Hybrid β NL β Keyword β Supersede β Mermaid β
β Extract β Query β + FTS5 β + Decay β DOT/CSV β
β β Engine β + Vector β + Temporal β β
ββββββββββββ΄ββββββββββ΄βββββββββββ΄βββββββββββββ΄ββββββββββ€
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Extraction Layer β β
β β βββββββββββββββββββ ββββββββββββββββββββββββββββββ β β
β β β Local (free) β β LLM (fallback, optional) β β β
β β β Rule-based NER β β OpenAI / Anthropic / Ollamaβ β β
β β β Pattern match β β High-quality extraction β β β
β β βββββββββββββββββββ ββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Embedding Layer β β
β β βββββββββββββββββββ ββββββββββββββββββββββββββββββ β β
β β β Local (free) β β API (optional, higher-dim) β β β
β β β N-gram 256d β β text-embedding-3-small β β β
β β β Cosine in JS β β 1536d, better quality β β β
β β βββββββββββββββββββ ββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β GraphEngine (SQLite + WAL + FTS5) β
β Entities β Relationships β Embeddings β FTS5 Index β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- SQLite β Single file, WAL mode, FTS5 full-text search, schema v4
- Hybrid extraction β Local rule-based (free) + LLM fallback (optional)
- Local embeddings β N-gram 256d vectors, cosine similarity in JS
- NL Query Engine β 12+ regex patterns + smart entity-name fallback
- Graph traversal β BFS pathfinding up to 5 hops
- Temporal facts β valid_from/valid_until, supersession, never-delete
- Confidence decay β Unused facts lose confidence (min 0.1)
- Relation normalization β Synonyms merged, vague relations rejected
- Deduplication β Levenshtein-based entity merging + relation dedup
- MCP server β stdio protocol for Claude Code, Cursor, Gemini CLI
- Persistence β Survives process restarts, session resets, and agent reboots
β Unit tests: 38/38 pass
β NL Query accuracy: 10/10 (local), 9.5/10 (plugin E2E)
β Path finding: 4/4 pass
β Edge cases: graceful handling, zero crashes
β Zero hallucination: no fabricated relationships
β Persistence: data survives /new, /reset, gateway restart
PRs welcome! See CONTRIBUTING.md.
git clone https://github.com/KLSGG/agent-memory-graph
cd agent-memory-graph
npm install
npm test # 38 tests
npm run dev # Watch modeMIT β Use it however you want.
Built for OpenClaw agents that need to remember.