Gomaa — Autonomous Agent Memory OS. Persistent memory system for AI agents with Obsidian vault integration, hybrid RRF search, knowledge graphs, security gates, and MCP server.
30
stars
45
commits
Python
primary language
Sep 1, 2026
updated
Production-grade, local-first hierarchical memory engine for autonomous AI agents.
Gomaa equips AI agents (Hermes, OpenClaw, Claude Desktop, Cursor, Windsurf, CrewAI, LangChain) with permanent, structured long-term memory. It bridges human-readable Obsidian Markdown Vaults with high-speed PostgreSQL + pgvector (HNSW) or zero-config SQLite WAL, powering hybrid Reciprocal Rank Fusion (RRF) search, wikilink knowledge graphs, Ebbinghaus temporal decay, cross-agent fleet sharing, and asynchronous Google Drive cloud synchronization.
Most AI memory systems suffer from three fundamental flaws:
Gomaa solves this:
[[Wiki Links]] and YAML frontmatter.#pinned memories stay permanent.wing = domain/project, room = channel/topic) isolates context strictly.shared_db while keeping private databases isolated.Choose between two straightforward deployment modes depending on your setup:
Best for: Standalone agents, individual developer workstations (Claude Desktop, Cursor IDE, Windsurf, CLI tools). Zero external database installation required (<1MB package size).
Run this single command in your terminal to install Gomaa, initialize your local Obsidian vault, and generate ready-to-copy MCP configurations:
curl -fsSL https://raw.githubusercontent.com/M4F-S/gomaa/main/install.sh | bash
# 1. Install lightweight core
pip install gomaa
# 2. Initialize local memory vault (~/.gomaa/vault)
gomaa init
# 3. Launch interactive web knowledge graph dashboard
gomaa dashboard
Add this MCP block to your agent configuration file:
claude_desktop_config.json){
"mcpServers": {
"gomaa": {
"command": "python3",
"args": ["-m", "gomaa", "server"],
"env": {
"MEMORY_VAULT_PATH": "~/.gomaa/vault",
"MEMORY_DEFAULT_WING": "general"
}
}
}
}
.cursor/mcp.json){
"mcpServers": {
"gomaa": {
"command": "python3",
"args": ["-m", "gomaa", "server"],
"env": {
"MEMORY_VAULT_PATH": "~/.gomaa/vault",
"MEMORY_DEFAULT_WING": "codebase"
}
}
}
}
Best for: Multi-agent swarms (Hermes, OpenClaw, CrewAI fleets), production servers, and large-scale vector search requiring HNSW indexing, cross-agent shared_db, and centralized embedding services.
Spin up PostgreSQL 16 with pgvector, pre-configured memory databases, and the Gomaa MCP server in 5 seconds:
git clone https://github.com/M4F-S/gomaa.git
cd gomaa
docker compose up -d
# 1. Install Gomaa with all production extras (pgvector, fastembed, server, gdrive)
pip install "gomaa[all]"
# 2. Configure your PostgreSQL connection strings
export MEMORY_DB_DSN="postgresql://gomaa:gomaa_secure_password@localhost:15432/gomaa"
export MEMORY_SHARED_DSN="postgresql://gomaa:gomaa_secure_password@localhost:15432/shared_db"
export MEMORY_VAULT_PATH="~/.gomaa/vault"
# 3. Launch the visual Web Knowledge Graph Dashboard
gomaa dashboard --port 8765
shared_db)| Feature | Description | Benefit |
|---|---|---|
| 🤖 MCP Native (v2024-11-05) | Standardized stdio JSON-RPC protocol server | Seamless drop-in for Claude, Cursor, Windsurf, Hermes, OpenClaw |
| 🔎 High-Recall HNSW Vector Search | pgvector HNSW indexing with vector_cosine_ops (m=16, ef_construction=64) | Sub-millisecond vector recall without clustering retraining |
| ⚖️ Hybrid RRF Retrieval | Reciprocal Rank Fusion of Dense Embeddings (1.0) + GIN FTS (0.8) + Graph (0.6) + Salience (0.2) | Captures exact technical keywords (CVEs, code tokens) & fuzzy semantics |
| 🏛️ Wing & Room Scoping | 2-level taxonomy (wing = domain/project, room = channel/topic) | Eliminates context window bloating & cross-domain hallucination |
| 🌐 Cross-Agent Shared Memory | Central shared_db queryable across multi-agent fleets with credential screening | Collective fleet intelligence without compromising private databases |
| ☁️ Async Google Drive Sync | Local-first bidirectional sync engine with MD5 diffing and .conflict.md branch resolution | Sub-millisecond agent I/O locally + automatic cloud backup & team sharing |
| ⏳ Ebbinghaus Temporal Decay | Exponential decay $Salience_t = Salience_0 \times (0.95)^{\Delta t}$ with 90-day auto-archive | Auto-prunes transient noise while keeping active memories sharp |
| 📌 Pinned Memory Immunity | Permanent immunity to decay via pinned=True or #pinned tags | Guarantees foundational instructions and core rules never fade |
| 📖 Obsidian Zettelkasten | Writes human-readable Markdown notes with YAML frontmatter & [[Wiki Links]] | Direct visual inspection, editing, and graph visualization in Obsidian |
| 📜 Turn-Aware Ingestor | 1,500-char sliding-window chunking with 200-char overlap along turn boundaries | Preserves entire conversation history without breaking code blocks |
| 🛡️ Prompt Injection Armor | Neutralizes control tokens (`< | im_start |
| 🎨 Native Aurora Dashboard | Zero-dependency embedded web knowledge graph (gomaa dashboard) | Real-time visual memory graph, 5-layer distribution charts & live query sandbox |
| 🧠 5 Cognitive Memory Layers | Scientific classification (Episodic, Semantic, Procedural, Social, Preferential) | Eliminates cross-domain noise and structures long-term agent understanding |
| 📦 Token-Budgeted Assembler | Packs top-salience memories into exact LLM prompt budgets with XML escaping | Direct drop-in context injection for LLM system prompts without overflow |
| 🔌 Framework Adapters | Native integrations for LangChain, LangGraph, and CrewAI | Drop-in multi-agent swarm memory with zero boilerplate |
| 🔄 Zero-Config SQLite Light Mode | Automatic fallback to local SQLite WAL when PostgreSQL is offline | 5-second setup with 100% feature parity for standalone developer workstations |
flowchart TD
subgraph Clients["🤖 AI Agents & LLM Clients"]
Claude["Claude Desktop / Cursor"]
Hermes["Hermes 5-Agent Fleet"]
Swarm["CrewAI / LangGraph Swarms"]
end
subgraph Core["🧠 Gomaa Core Engine (v3.5.0)"]
direction TB
MCP["MCP JSON-RPC Server\n(9 Tools · Stdio)"]
Security["Admission & Security Guard\n(Credential Regex · Control Token Sanitizer)"]
RRF["Hybrid RRF Ranker\nDense(1.0) + FTS(0.8) + Graph(0.6) + Salience(0.2)"]
Decay["Ebbinghaus Temporal Decay Engine\n(Exponential Decay · Pinned Immunity)"]
Assembler["Token-Budgeted Context Assembler\n(Structured XML Prompt Enclosure)"]
end
subgraph Storage["💾 Dual Storage Topology"]
Postgres[("🐘 PostgreSQL 16 + pgvector\nHNSW Indexing · GIN FTS\nPrivate DBs + shared_db")]
SQLite[("⚡ SQLite WAL\nZero-Config Local Mode")]
Vault["📖 Obsidian Markdown Vault\nYAML Frontmatter · [[Wikilinks]] Graph"]
end
subgraph Cloud["☁️ Remote Sync (Optional)"]
GDrive["Google Drive Cloud Sync\n(MD5 Diffing · Conflict Branching)"]
end
Clients -->|MCP stdio / Python SDK| MCP
MCP --> Security
Security --> RRF
RRF <--> Postgres
RRF <--> SQLite
RRF <--> Vault
Decay --> Postgres
Decay --> SQLite
Assembler --> Clients
Vault <-->|Async Daemon / Cron| GDrive
Memory cross-contamination is a major failure mode in multi-agent fleets. Gomaa structures memory as a 2-level physical palace:
wing (Domain/Project): Top-level domain boundary (e.g. ecommerce, pentest, devops, shared).room (Topic/Channel): Granular topic partition (e.g. database, firewall, stripe_api).Queries can be scoped tightly to a specific wing or room, preventing marketing prompts from recalling penetration testing findings.
Standard vector search fails on exact technical strings (e.g. CVE-2024-38077, 0x7fff5fbff8c0), while keyword search fails on semantic concepts. Gomaa executes multi-candidate retrieval and merges results using weighted RRF:
$$\text{RRF Score}(d) = \sum_{m \in \text{modes}} w_m \cdot \frac{1}{k + \text{rank}_m(d)} + 0.2 \cdot \text{Salience}(d)$$
tsvector weighted with title as A and content as B).[[Wiki Links]]).shared_db)In autonomous multi-agent environments, agents maintain isolated private databases (toy_db, old_db, candy_db, etc.) to prevent state corruption. However, collective intelligence requires sharing global policies and verified facts.
memory_publish_shared, vetted notes are published to shared_db.sk-ant-), Google Gemini keys (AIza...), HuggingFace tokens (hf_...), OpenAI keys (sk-proj-...), AWS access keys (AKIA...), Slack tokens (xox-), and private keys.memory_recall queries both the private store and shared_db. If the shared database is temporarily unreachable, it degrades gracefully without interrupting the agent.Memories naturally lose relevance over time. Gomaa implements Herman Ebbinghaus's exponential forgetting curve:
$$\text{Salience}(t) = \text{Salience}0 \times (0.95)^{\Delta t{\text{days}}}$$
last_accessed_at, resetting its decay.status = 'archived'.pinned=True or tagged #pinned receive permanent immunity from temporal decay ($\text{Salience} = 1.0$).Every memory created by an agent is simultaneously written as a human-readable .md file inside your Obsidian vault:
title, date, tags, type, salience, wing, and room.[[Target Note]] are automatically parsed into bi-directional edges in PostgreSQL.Conversational transcripts often contain crucial nuances lost in lossy summarization. memory_ingest_session:
User:, Assistant:, ### Turn, **Human**:).[[Session ... Turn 01 Part 02]] wikilinks, preserving code blocks, execution traces, and conversational flow.Keep your agent vaults securely backed up and synchronized across multiple machines or mobile devices:
NoteName.conflict-YYYYMMDD-HHMMSS.md, preventing data loss.GOOGLE_APPLICATION_CREDENTIALS, GDRIVE_SERVICE_ACCOUNT_JSON) and OAuth2 user tokens (GDRIVE_TOKEN_JSON).Gomaa adapts to any deployment resource budget:
gomaa.embed_service): Hosts sentence-transformers in a single dedicated container serving multiple agent containers over HTTP (MEMORY_EMBED_URL).all-MiniLM-L6-v2, 384-dimensional).is_relative_to) ensure file operations cannot escape the vault root..note.pid.tmp) and renamed atomically, with automatic fallback for EXDEV cross-device volume mounts.<|im_start|>, <|system|>, [INST], <<SYS>>) in prose while preserving code blocks verbatim.<recalled_memory_context id="..." title="..." source="..."> tags with internal tag escaping, ensuring host LLMs never confuse recalled memories with active system directives.All 9 tools are natively exposed to agents over standard MCP JSON-RPC stdio:
memory_rememberStore a private memory note in the vault with semantic embedding, tags, and hierarchical scoping.
{
"title": "PostgreSQL HNSW Tuning",
"content": "For datasets >10,000 vectors, use HNSW with m=16 and ef_construction=64 for optimal recall.",
"tags": ["database", "pgvector", "performance"],
"wing": "engineering",
"room": "databases",
"salience": 0.8,
"pinned": true
}
memory_publish_sharedPublish a sanitized, vetted finding or policy to the cross-agent shared fleet memory (shared_db).
{
"title": "Fleet Security Policy: SSL Verification",
"content": "All internal agent HTTP requests must enforce SSL certificate validation.",
"tags": ["security", "policy"],
"wing": "shared",
"room": "general"
}
memory_recallSearch memories across private and shared fleet databases using hybrid RRF, HNSW vectors, keywords, or graph.
{
"query": "HNSW index configuration parameters",
"mode": "hybrid",
"top_k": 5,
"scope": {
"wing": "engineering",
"room": "databases"
},
"include_shared": true
}
memory_ingest_sessionIngest and chunk a complete conversation transcript verbatim along turn boundaries.
{
"transcript": "User: How do we configure pgvector?\nAssistant: Use CREATE EXTENSION vector; then create an HNSW index.",
"wing": "engineering",
"room": "sessions"
}
memory_timelineInspect recent memory operations (remember, recall, remind, consolidate) in chronological order.
{
"limit": 20
}
memory_historyView version history and past edit snapshots of a specific memory note before updates.
{
"title": "PostgreSQL HNSW Tuning",
"limit": 5
}
memory_remind_meSchedule a future prospective reminder or recurring task.
{
"title": "Rotate Database Credentials",
"content": "Verify that all 5 agent connection pools are refreshed with new passwords.",
"trigger_at": "2026-09-01T00:00:00Z",
"recurring": "monthly"
}
memory_assemble_contextRetrieve, rank, and pack high-salience memories into a strict token-budgeted XML prompt block ready for direct LLM system prompt injection.
{
"query": "Kubernetes staging deployment limits",
"max_tokens": 1500,
"mode": "hybrid",
"scope": {
"wing": "infrastructure"
},
"include_shared": true
}
memory_auditGet real-time memory health metrics, store backend status, request counts, and active wings.
{}
In multi-agent production setups (such as the 5-agent Hermes fleet), Gomaa isolates agent databases on an internal Docker network while providing shared intelligence:
┌─────────────────────────────────────────┐
│ Production VPS (${VPS_HOST}) │
└────────────────────┬────────────────────┘
│
┌───────────────────┬──────────────────┼───────────────────┬──────────────────┐
▼ ▼ ▼ ▼ ▼
┌──────────────────┐┌──────────────────┐┌──────────────────┐┌──────────────────┐┌──────────────────┐
│ hermes-agent ││ hermes-assistant ││ hermes-marketing ││ hermes-pentest ││ hermes-trader │
│ (Toy) ││ (Old) ││ (Candy) ││ (Pencil) ││ (Coin) │
│ Database: ││ Database: ││ Database: ││ Database: ││ Database: │
│ toy_db ││ old_db ││ candy_db ││ pencil_db ││ trader_db │
└────────┬─────────┘└────────┬─────────┘└────────┬─────────┘└────────┬─────────┘└────────┬─────────┘
│ │ │ │ │
└───────────────────┴──────────────────┼───────────────────┴──────────────────┘
│
▼
┌───────────────────────────────────┐
│ PostgreSQL + pgvector (HNSW) │
│ - Private DBs: toy_db, old_db.. │
│ - Shared DB: shared_db │
└───────────────────────────────────┘
~/.hermes/config.yaml)mcp_servers:
obsidian_memory:
command: python3
args: ["-m", "gomaa", "server"]
env:
MEMORY_DB_DSN: "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/toy_db"
MEMORY_SHARED_DSN: "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/shared_db"
MEMORY_VAULT_PATH: "/opt/data/vault"
openclaw-config.yaml)plugins:
mcp_servers:
gomaa:
command: "python3"
args: ["-m", "gomaa", "server"]
env:
MEMORY_VAULT_PATH: "~/.openclaw/vault"
MEMORY_DEFAULT_WING: "openclaw"
Drop-in memory adapter using Gomaa's token-budgeted prompt context assembler:
from gomaa.adapters.langchain import GomaaMemory
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI
memory = GomaaMemory(
wing="support_agent",
room="tickets",
max_tokens=1500
)
conversation = ConversationChain(
llm=ChatOpenAI(model="gpt-4o"),
memory=memory,
verbose=True
)
conversation.predict(input="Our PostgreSQL server is at 10.0.0.5 on port 5432.")
Domain-isolated memory handler for CrewAI agents:
from gomaa.adapters.crewai import GomaaMemoryHandler
from crewai import Agent, Crew, Task
mem_handler = GomaaMemoryHandler(crew_name="security_squad")
agent = Agent(
role="Penetration Tester",
goal="Discover vulnerabilities in staging infrastructure",
memory=True
)
# Save task findings with automatic domain wing isolation
mem_handler.save(
value="Port 8080 open on staging host 10.0.0.5 running vulnerable Tomcat",
metadata={"task": "recon", "salience": 0.9, "pinned": True},
agent_role="Penetration Tester"
)
from gomaa import UnifiedMemorySystem
mem = UnifiedMemorySystem(
vault_path="~/.agent/vault",
dsn="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/agent_db",
shared_dsn="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/shared_db"
)
# Remember fact
mem.remember(
title="Kubernetes Cluster Policy",
content="Deployments in staging must specify resource memory limits.",
wing="infrastructure",
room="k8s",
tags=["kubernetes", "policy"],
pinned=True
)
# Assemble token-budgeted context for LLM prompt
ctx = mem.assemble_context(
query="staging memory limits",
max_tokens=1500,
scope={"wing": "infrastructure"}
)
print(ctx["context_text"])
Gomaa includes a full-featured management CLI:
# 1. Initialize local vault & generate ready-to-copy MCP configurations
gomaa init --path ~/.gomaa/vault
# 2. Launch interactive Aurora Web Knowledge Graph Dashboard
gomaa dashboard --port 8765
# 3. Store a memory note
gomaa remember "API Architecture" "Uses Bearer JWT auth." --tags security auth --wing backend --room api --salience 0.8 --pinned
# 4. Publish shared fleet memory
gomaa publish-shared "Global Production Policy" "Always check SSL certs." --wing devops
# 5. Search memories (hybrid / semantic / keyword / graph)
gomaa recall "JWT authentication" --mode hybrid --top-k 5 --wing backend
# 6. Assemble token-budgeted prompt context block
gomaa assemble-context "production policy" --max-tokens 1500 --wing devops
# 7. View activity timeline
gomaa timeline --limit 20
# 8. Trigger Ebbinghaus decay & link reconciliation
gomaa consolidate --decay-rate 0.95 --archive-threshold 0.05
# 9. Check system statistics & health
gomaa stats
# 10. Synchronize with Google Drive (One-off pass or daemon mode)
gomaa sync-gdrive --folder "My-Agent-Vault" --credentials service-account.json
gomaa sync-gdrive --daemon --interval 60
# 11. Run standalone Centralized Embedding Microservice
gomaa embed-service --host 0.0.0.0 --port 8000 --model all-MiniLM-L6-v2
| Variable | Default | Description |
|---|---|---|
MEMORY_VAULT_PATH | ~/.gomaa/vault | Filesystem path to the local Obsidian Markdown vault directory |
MEMORY_DB_DSN | (none) | PostgreSQL DSN (e.g. postgresql://user:pass@host:5432/db). If unset, uses SQLite |
MEMORY_SHARED_DSN | (none) | PostgreSQL DSN for the optional cross-agent shared fleet database |
MEMORY_AGENT_NAME | local-agent | Identifier for the origin agent in multi-agent fleet deployments |
MEMORY_EMBED_URL | (none) | URL of remote centralized embedding microservice (e.g. http://localhost:8000) |
MEMORY_REQUIRE_POSTGRES | false | Set true to raise an error instead of falling back to SQLite if PostgreSQL fails |
GOOGLE_APPLICATION_CREDENTIALS | (none) | File path to Google Cloud Service Account JSON for Google Drive synchronization |
GDRIVE_SERVICE_ACCOUNT_JSON | (none) | Stringified JSON content of Google Cloud Service Account credentials |
GDRIVE_TOKEN_JSON | (none) | Stringified JSON content of authorized Google OAuth2 user token |
TOKENIZERS_PARALLELISM | false | Disables HuggingFace tokenizer forks to preserve stdio JSON-RPC stream integrity |
HF_HUB_DISABLE_PROGRESS_BARS | 1 | Disables progress bars in stdio to keep MCP streams pristine |
HF_HUB_OFFLINE | 0 | Set 1 to run SentenceTransformers 100% offline using local cache |
TRANSFORMERS_OFFLINE | 0 | Set 1 to prevent transformers from making external HuggingFace network requests |
Benchmarked on Apple Silicon (M-series) / Ubuntu 24.04 LTS against a live knowledge graph of notes with 384-dimensional vector embeddings:
| Operation | Implementation | Mean Latency | P95 Latency | Throughput |
|---|---|---|---|---|
| Cold Engine Init | SQLite WAL + Obsidian Vault | 6.28 ms | 6.50 ms | ~160 init/s |
| Neural Ingest | FastEmbed ONNX + SQLite + Markdown File IO | 13.50 ms | 21.47 ms | ~75 notes/s |
| Neural Recall | Query Embedding + Dot Product + Keyword RRF | 13.71 ms | 14.79 ms | ~73 queries/s |
| Keyword FTS Search | SQLite FTS5 / PostgreSQL GIN tsvector | 0.99 ms | 1.24 ms | ~1,010 queries/s |
| Graph Traversal | Recursive CTE / In-Memory Wikilink Walk | 0.83 ms | 0.97 ms | ~1,200 walks/s |
| Context Assembler | Top-K Recall + Token Budgeting + XML Packing | 6.12 ms | 6.45 ms | ~163 assemblies/s |
Gomaa maintains a comprehensive automated test suite spanning 28 test modules:
collected 94 items
tests/test_adapters.py .. [ 2%]
tests/test_assemble_context.py ... [ 5%]
tests/test_chunking.py . [ 6%]
tests/test_cli_init.py .. [ 8%]
tests/test_compat.py .... [ 12%]
tests/test_consolidation.py .. [ 14%]
tests/test_dashboard.py ...... [ 21%]
tests/test_embedder.py ... [ 24%]
tests/test_embedder_offline.py . [ 25%]
tests/test_embedder_v32.py .. [ 27%]
tests/test_fts_websearch.py . [ 28%]
tests/test_gdrive_safe_path.py ..... [ 34%]
tests/test_gdrive_sync.py ... [ 37%]
tests/test_graph_cycles.py . [ 38%]
tests/test_injection_defense.py ... [ 41%]
tests/test_integration.py ... [ 44%]
tests/test_mcp.py .. [ 46%]
tests/test_mcp_edge_cases.py .. [ 48%]
tests/test_mcp_server.py .............. [ 63%]
tests/test_reconcile_links.py . [ 64%]
tests/test_remind_me_sqlite.py .... [ 69%]
tests/test_security.py ...... [ 75%]
tests/test_security_expanded.py ..... [ 80%]
tests/test_shared_memory.py .. [ 82%]
tests/test_sqlite.py ..... [ 88%]
tests/test_store_factory.py ... [ 91%]
tests/test_vault.py ..... [ 96%]
tests/test_vault_security.py ... [100%]
======================= 94 passed, 41 warnings in 13.38s =======================
# 1. Run all unit & integration tests locally (Light Mode with SQLite)
uv run pytest tests/ -v
# 2. Run with coverage report
uv run pytest tests/ --cov=gomaa --cov-report=term-missing
# 3. Run full test suite including live PostgreSQL + pgvector tests
MEMORY_DB_DSN="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}" uv run pytest tests/ -v
tmp_path) to generate ephemeral Obsidian vaults and SQLite databases, ensuring zero state pollution between runs..note.pid.tmp) are cleaned up immediately.tests/test_injection_defense.py and tests/test_security.py continuously verify that LLM control tokens, DAN mode overrides, path traversal attempts, and credential leaks are neutralized.Apache-2.0 License. Built for the open autonomous agent ecosystem. See LICENSE for full details.
Python
80.9%
HTML
15.2%
Shell
3.2%
Gomaa — Autonomous Agent Memory OS. Persistent memory system for AI agents with Obsidian vault integration, hybrid RRF search, knowledge graphs, security gates, and MCP server.
30
stars
45
commits
Python
primary language
Sep 1, 2026
updated
Production-grade, local-first hierarchical memory engine for autonomous AI agents.
Gomaa equips AI agents (Hermes, OpenClaw, Claude Desktop, Cursor, Windsurf, CrewAI, LangChain) with permanent, structured long-term memory. It bridges human-readable Obsidian Markdown Vaults with high-speed PostgreSQL + pgvector (HNSW) or zero-config SQLite WAL, powering hybrid Reciprocal Rank Fusion (RRF) search, wikilink knowledge graphs, Ebbinghaus temporal decay, cross-agent fleet sharing, and asynchronous Google Drive cloud synchronization.
Most AI memory systems suffer from three fundamental flaws:
Gomaa solves this:
[[Wiki Links]] and YAML frontmatter.#pinned memories stay permanent.wing = domain/project, room = channel/topic) isolates context strictly.shared_db while keeping private databases isolated.Choose between two straightforward deployment modes depending on your setup:
Best for: Standalone agents, individual developer workstations (Claude Desktop, Cursor IDE, Windsurf, CLI tools). Zero external database installation required (<1MB package size).
Run this single command in your terminal to install Gomaa, initialize your local Obsidian vault, and generate ready-to-copy MCP configurations:
curl -fsSL https://raw.githubusercontent.com/M4F-S/gomaa/main/install.sh | bash
# 1. Install lightweight core
pip install gomaa
# 2. Initialize local memory vault (~/.gomaa/vault)
gomaa init
# 3. Launch interactive web knowledge graph dashboard
gomaa dashboard
Add this MCP block to your agent configuration file:
claude_desktop_config.json){
"mcpServers": {
"gomaa": {
"command": "python3",
"args": ["-m", "gomaa", "server"],
"env": {
"MEMORY_VAULT_PATH": "~/.gomaa/vault",
"MEMORY_DEFAULT_WING": "general"
}
}
}
}
.cursor/mcp.json){
"mcpServers": {
"gomaa": {
"command": "python3",
"args": ["-m", "gomaa", "server"],
"env": {
"MEMORY_VAULT_PATH": "~/.gomaa/vault",
"MEMORY_DEFAULT_WING": "codebase"
}
}
}
}
Best for: Multi-agent swarms (Hermes, OpenClaw, CrewAI fleets), production servers, and large-scale vector search requiring HNSW indexing, cross-agent shared_db, and centralized embedding services.
Spin up PostgreSQL 16 with pgvector, pre-configured memory databases, and the Gomaa MCP server in 5 seconds:
git clone https://github.com/M4F-S/gomaa.git
cd gomaa
docker compose up -d
# 1. Install Gomaa with all production extras (pgvector, fastembed, server, gdrive)
pip install "gomaa[all]"
# 2. Configure your PostgreSQL connection strings
export MEMORY_DB_DSN="postgresql://gomaa:gomaa_secure_password@localhost:15432/gomaa"
export MEMORY_SHARED_DSN="postgresql://gomaa:gomaa_secure_password@localhost:15432/shared_db"
export MEMORY_VAULT_PATH="~/.gomaa/vault"
# 3. Launch the visual Web Knowledge Graph Dashboard
gomaa dashboard --port 8765
shared_db)| Feature | Description | Benefit |
|---|---|---|
| 🤖 MCP Native (v2024-11-05) | Standardized stdio JSON-RPC protocol server | Seamless drop-in for Claude, Cursor, Windsurf, Hermes, OpenClaw |
| 🔎 High-Recall HNSW Vector Search | pgvector HNSW indexing with vector_cosine_ops (m=16, ef_construction=64) | Sub-millisecond vector recall without clustering retraining |
| ⚖️ Hybrid RRF Retrieval | Reciprocal Rank Fusion of Dense Embeddings (1.0) + GIN FTS (0.8) + Graph (0.6) + Salience (0.2) | Captures exact technical keywords (CVEs, code tokens) & fuzzy semantics |
| 🏛️ Wing & Room Scoping | 2-level taxonomy (wing = domain/project, room = channel/topic) | Eliminates context window bloating & cross-domain hallucination |
| 🌐 Cross-Agent Shared Memory | Central shared_db queryable across multi-agent fleets with credential screening | Collective fleet intelligence without compromising private databases |
| ☁️ Async Google Drive Sync | Local-first bidirectional sync engine with MD5 diffing and .conflict.md branch resolution | Sub-millisecond agent I/O locally + automatic cloud backup & team sharing |
| ⏳ Ebbinghaus Temporal Decay | Exponential decay $Salience_t = Salience_0 \times (0.95)^{\Delta t}$ with 90-day auto-archive | Auto-prunes transient noise while keeping active memories sharp |
| 📌 Pinned Memory Immunity | Permanent immunity to decay via pinned=True or #pinned tags | Guarantees foundational instructions and core rules never fade |
| 📖 Obsidian Zettelkasten | Writes human-readable Markdown notes with YAML frontmatter & [[Wiki Links]] | Direct visual inspection, editing, and graph visualization in Obsidian |
| 📜 Turn-Aware Ingestor | 1,500-char sliding-window chunking with 200-char overlap along turn boundaries | Preserves entire conversation history without breaking code blocks |
| 🛡️ Prompt Injection Armor | Neutralizes control tokens (`< | im_start |
| 🎨 Native Aurora Dashboard | Zero-dependency embedded web knowledge graph (gomaa dashboard) | Real-time visual memory graph, 5-layer distribution charts & live query sandbox |
| 🧠 5 Cognitive Memory Layers | Scientific classification (Episodic, Semantic, Procedural, Social, Preferential) | Eliminates cross-domain noise and structures long-term agent understanding |
| 📦 Token-Budgeted Assembler | Packs top-salience memories into exact LLM prompt budgets with XML escaping | Direct drop-in context injection for LLM system prompts without overflow |
| 🔌 Framework Adapters | Native integrations for LangChain, LangGraph, and CrewAI | Drop-in multi-agent swarm memory with zero boilerplate |
| 🔄 Zero-Config SQLite Light Mode | Automatic fallback to local SQLite WAL when PostgreSQL is offline | 5-second setup with 100% feature parity for standalone developer workstations |
flowchart TD
subgraph Clients["🤖 AI Agents & LLM Clients"]
Claude["Claude Desktop / Cursor"]
Hermes["Hermes 5-Agent Fleet"]
Swarm["CrewAI / LangGraph Swarms"]
end
subgraph Core["🧠 Gomaa Core Engine (v3.5.0)"]
direction TB
MCP["MCP JSON-RPC Server\n(9 Tools · Stdio)"]
Security["Admission & Security Guard\n(Credential Regex · Control Token Sanitizer)"]
RRF["Hybrid RRF Ranker\nDense(1.0) + FTS(0.8) + Graph(0.6) + Salience(0.2)"]
Decay["Ebbinghaus Temporal Decay Engine\n(Exponential Decay · Pinned Immunity)"]
Assembler["Token-Budgeted Context Assembler\n(Structured XML Prompt Enclosure)"]
end
subgraph Storage["💾 Dual Storage Topology"]
Postgres[("🐘 PostgreSQL 16 + pgvector\nHNSW Indexing · GIN FTS\nPrivate DBs + shared_db")]
SQLite[("⚡ SQLite WAL\nZero-Config Local Mode")]
Vault["📖 Obsidian Markdown Vault\nYAML Frontmatter · [[Wikilinks]] Graph"]
end
subgraph Cloud["☁️ Remote Sync (Optional)"]
GDrive["Google Drive Cloud Sync\n(MD5 Diffing · Conflict Branching)"]
end
Clients -->|MCP stdio / Python SDK| MCP
MCP --> Security
Security --> RRF
RRF <--> Postgres
RRF <--> SQLite
RRF <--> Vault
Decay --> Postgres
Decay --> SQLite
Assembler --> Clients
Vault <-->|Async Daemon / Cron| GDrive
Memory cross-contamination is a major failure mode in multi-agent fleets. Gomaa structures memory as a 2-level physical palace:
wing (Domain/Project): Top-level domain boundary (e.g. ecommerce, pentest, devops, shared).room (Topic/Channel): Granular topic partition (e.g. database, firewall, stripe_api).Queries can be scoped tightly to a specific wing or room, preventing marketing prompts from recalling penetration testing findings.
Standard vector search fails on exact technical strings (e.g. CVE-2024-38077, 0x7fff5fbff8c0), while keyword search fails on semantic concepts. Gomaa executes multi-candidate retrieval and merges results using weighted RRF:
$$\text{RRF Score}(d) = \sum_{m \in \text{modes}} w_m \cdot \frac{1}{k + \text{rank}_m(d)} + 0.2 \cdot \text{Salience}(d)$$
tsvector weighted with title as A and content as B).[[Wiki Links]]).shared_db)In autonomous multi-agent environments, agents maintain isolated private databases (toy_db, old_db, candy_db, etc.) to prevent state corruption. However, collective intelligence requires sharing global policies and verified facts.
memory_publish_shared, vetted notes are published to shared_db.sk-ant-), Google Gemini keys (AIza...), HuggingFace tokens (hf_...), OpenAI keys (sk-proj-...), AWS access keys (AKIA...), Slack tokens (xox-), and private keys.memory_recall queries both the private store and shared_db. If the shared database is temporarily unreachable, it degrades gracefully without interrupting the agent.Memories naturally lose relevance over time. Gomaa implements Herman Ebbinghaus's exponential forgetting curve:
$$\text{Salience}(t) = \text{Salience}0 \times (0.95)^{\Delta t{\text{days}}}$$
last_accessed_at, resetting its decay.status = 'archived'.pinned=True or tagged #pinned receive permanent immunity from temporal decay ($\text{Salience} = 1.0$).Every memory created by an agent is simultaneously written as a human-readable .md file inside your Obsidian vault:
title, date, tags, type, salience, wing, and room.[[Target Note]] are automatically parsed into bi-directional edges in PostgreSQL.Conversational transcripts often contain crucial nuances lost in lossy summarization. memory_ingest_session:
User:, Assistant:, ### Turn, **Human**:).[[Session ... Turn 01 Part 02]] wikilinks, preserving code blocks, execution traces, and conversational flow.Keep your agent vaults securely backed up and synchronized across multiple machines or mobile devices:
NoteName.conflict-YYYYMMDD-HHMMSS.md, preventing data loss.GOOGLE_APPLICATION_CREDENTIALS, GDRIVE_SERVICE_ACCOUNT_JSON) and OAuth2 user tokens (GDRIVE_TOKEN_JSON).Gomaa adapts to any deployment resource budget:
gomaa.embed_service): Hosts sentence-transformers in a single dedicated container serving multiple agent containers over HTTP (MEMORY_EMBED_URL).all-MiniLM-L6-v2, 384-dimensional).is_relative_to) ensure file operations cannot escape the vault root..note.pid.tmp) and renamed atomically, with automatic fallback for EXDEV cross-device volume mounts.<|im_start|>, <|system|>, [INST], <<SYS>>) in prose while preserving code blocks verbatim.<recalled_memory_context id="..." title="..." source="..."> tags with internal tag escaping, ensuring host LLMs never confuse recalled memories with active system directives.All 9 tools are natively exposed to agents over standard MCP JSON-RPC stdio:
memory_rememberStore a private memory note in the vault with semantic embedding, tags, and hierarchical scoping.
{
"title": "PostgreSQL HNSW Tuning",
"content": "For datasets >10,000 vectors, use HNSW with m=16 and ef_construction=64 for optimal recall.",
"tags": ["database", "pgvector", "performance"],
"wing": "engineering",
"room": "databases",
"salience": 0.8,
"pinned": true
}
memory_publish_sharedPublish a sanitized, vetted finding or policy to the cross-agent shared fleet memory (shared_db).
{
"title": "Fleet Security Policy: SSL Verification",
"content": "All internal agent HTTP requests must enforce SSL certificate validation.",
"tags": ["security", "policy"],
"wing": "shared",
"room": "general"
}
memory_recallSearch memories across private and shared fleet databases using hybrid RRF, HNSW vectors, keywords, or graph.
{
"query": "HNSW index configuration parameters",
"mode": "hybrid",
"top_k": 5,
"scope": {
"wing": "engineering",
"room": "databases"
},
"include_shared": true
}
memory_ingest_sessionIngest and chunk a complete conversation transcript verbatim along turn boundaries.
{
"transcript": "User: How do we configure pgvector?\nAssistant: Use CREATE EXTENSION vector; then create an HNSW index.",
"wing": "engineering",
"room": "sessions"
}
memory_timelineInspect recent memory operations (remember, recall, remind, consolidate) in chronological order.
{
"limit": 20
}
memory_historyView version history and past edit snapshots of a specific memory note before updates.
{
"title": "PostgreSQL HNSW Tuning",
"limit": 5
}
memory_remind_meSchedule a future prospective reminder or recurring task.
{
"title": "Rotate Database Credentials",
"content": "Verify that all 5 agent connection pools are refreshed with new passwords.",
"trigger_at": "2026-09-01T00:00:00Z",
"recurring": "monthly"
}
memory_assemble_contextRetrieve, rank, and pack high-salience memories into a strict token-budgeted XML prompt block ready for direct LLM system prompt injection.
{
"query": "Kubernetes staging deployment limits",
"max_tokens": 1500,
"mode": "hybrid",
"scope": {
"wing": "infrastructure"
},
"include_shared": true
}
memory_auditGet real-time memory health metrics, store backend status, request counts, and active wings.
{}
In multi-agent production setups (such as the 5-agent Hermes fleet), Gomaa isolates agent databases on an internal Docker network while providing shared intelligence:
┌─────────────────────────────────────────┐
│ Production VPS (${VPS_HOST}) │
└────────────────────┬────────────────────┘
│
┌───────────────────┬──────────────────┼───────────────────┬──────────────────┐
▼ ▼ ▼ ▼ ▼
┌──────────────────┐┌──────────────────┐┌──────────────────┐┌──────────────────┐┌──────────────────┐
│ hermes-agent ││ hermes-assistant ││ hermes-marketing ││ hermes-pentest ││ hermes-trader │
│ (Toy) ││ (Old) ││ (Candy) ││ (Pencil) ││ (Coin) │
│ Database: ││ Database: ││ Database: ││ Database: ││ Database: │
│ toy_db ││ old_db ││ candy_db ││ pencil_db ││ trader_db │
└────────┬─────────┘└────────┬─────────┘└────────┬─────────┘└────────┬─────────┘└────────┬─────────┘
│ │ │ │ │
└───────────────────┴──────────────────┼───────────────────┴──────────────────┘
│
▼
┌───────────────────────────────────┐
│ PostgreSQL + pgvector (HNSW) │
│ - Private DBs: toy_db, old_db.. │
│ - Shared DB: shared_db │
└───────────────────────────────────┘
~/.hermes/config.yaml)mcp_servers:
obsidian_memory:
command: python3
args: ["-m", "gomaa", "server"]
env:
MEMORY_DB_DSN: "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/toy_db"
MEMORY_SHARED_DSN: "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/shared_db"
MEMORY_VAULT_PATH: "/opt/data/vault"
openclaw-config.yaml)plugins:
mcp_servers:
gomaa:
command: "python3"
args: ["-m", "gomaa", "server"]
env:
MEMORY_VAULT_PATH: "~/.openclaw/vault"
MEMORY_DEFAULT_WING: "openclaw"
Drop-in memory adapter using Gomaa's token-budgeted prompt context assembler:
from gomaa.adapters.langchain import GomaaMemory
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI
memory = GomaaMemory(
wing="support_agent",
room="tickets",
max_tokens=1500
)
conversation = ConversationChain(
llm=ChatOpenAI(model="gpt-4o"),
memory=memory,
verbose=True
)
conversation.predict(input="Our PostgreSQL server is at 10.0.0.5 on port 5432.")
Domain-isolated memory handler for CrewAI agents:
from gomaa.adapters.crewai import GomaaMemoryHandler
from crewai import Agent, Crew, Task
mem_handler = GomaaMemoryHandler(crew_name="security_squad")
agent = Agent(
role="Penetration Tester",
goal="Discover vulnerabilities in staging infrastructure",
memory=True
)
# Save task findings with automatic domain wing isolation
mem_handler.save(
value="Port 8080 open on staging host 10.0.0.5 running vulnerable Tomcat",
metadata={"task": "recon", "salience": 0.9, "pinned": True},
agent_role="Penetration Tester"
)
from gomaa import UnifiedMemorySystem
mem = UnifiedMemorySystem(
vault_path="~/.agent/vault",
dsn="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/agent_db",
shared_dsn="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/shared_db"
)
# Remember fact
mem.remember(
title="Kubernetes Cluster Policy",
content="Deployments in staging must specify resource memory limits.",
wing="infrastructure",
room="k8s",
tags=["kubernetes", "policy"],
pinned=True
)
# Assemble token-budgeted context for LLM prompt
ctx = mem.assemble_context(
query="staging memory limits",
max_tokens=1500,
scope={"wing": "infrastructure"}
)
print(ctx["context_text"])
Gomaa includes a full-featured management CLI:
# 1. Initialize local vault & generate ready-to-copy MCP configurations
gomaa init --path ~/.gomaa/vault
# 2. Launch interactive Aurora Web Knowledge Graph Dashboard
gomaa dashboard --port 8765
# 3. Store a memory note
gomaa remember "API Architecture" "Uses Bearer JWT auth." --tags security auth --wing backend --room api --salience 0.8 --pinned
# 4. Publish shared fleet memory
gomaa publish-shared "Global Production Policy" "Always check SSL certs." --wing devops
# 5. Search memories (hybrid / semantic / keyword / graph)
gomaa recall "JWT authentication" --mode hybrid --top-k 5 --wing backend
# 6. Assemble token-budgeted prompt context block
gomaa assemble-context "production policy" --max-tokens 1500 --wing devops
# 7. View activity timeline
gomaa timeline --limit 20
# 8. Trigger Ebbinghaus decay & link reconciliation
gomaa consolidate --decay-rate 0.95 --archive-threshold 0.05
# 9. Check system statistics & health
gomaa stats
# 10. Synchronize with Google Drive (One-off pass or daemon mode)
gomaa sync-gdrive --folder "My-Agent-Vault" --credentials service-account.json
gomaa sync-gdrive --daemon --interval 60
# 11. Run standalone Centralized Embedding Microservice
gomaa embed-service --host 0.0.0.0 --port 8000 --model all-MiniLM-L6-v2
| Variable | Default | Description |
|---|---|---|
MEMORY_VAULT_PATH | ~/.gomaa/vault | Filesystem path to the local Obsidian Markdown vault directory |
MEMORY_DB_DSN | (none) | PostgreSQL DSN (e.g. postgresql://user:pass@host:5432/db). If unset, uses SQLite |
MEMORY_SHARED_DSN | (none) | PostgreSQL DSN for the optional cross-agent shared fleet database |
MEMORY_AGENT_NAME | local-agent | Identifier for the origin agent in multi-agent fleet deployments |
MEMORY_EMBED_URL | (none) | URL of remote centralized embedding microservice (e.g. http://localhost:8000) |
MEMORY_REQUIRE_POSTGRES | false | Set true to raise an error instead of falling back to SQLite if PostgreSQL fails |
GOOGLE_APPLICATION_CREDENTIALS | (none) | File path to Google Cloud Service Account JSON for Google Drive synchronization |
GDRIVE_SERVICE_ACCOUNT_JSON | (none) | Stringified JSON content of Google Cloud Service Account credentials |
GDRIVE_TOKEN_JSON | (none) | Stringified JSON content of authorized Google OAuth2 user token |
TOKENIZERS_PARALLELISM | false | Disables HuggingFace tokenizer forks to preserve stdio JSON-RPC stream integrity |
HF_HUB_DISABLE_PROGRESS_BARS | 1 | Disables progress bars in stdio to keep MCP streams pristine |
HF_HUB_OFFLINE | 0 | Set 1 to run SentenceTransformers 100% offline using local cache |
TRANSFORMERS_OFFLINE | 0 | Set 1 to prevent transformers from making external HuggingFace network requests |
Benchmarked on Apple Silicon (M-series) / Ubuntu 24.04 LTS against a live knowledge graph of notes with 384-dimensional vector embeddings:
| Operation | Implementation | Mean Latency | P95 Latency | Throughput |
|---|---|---|---|---|
| Cold Engine Init | SQLite WAL + Obsidian Vault | 6.28 ms | 6.50 ms | ~160 init/s |
| Neural Ingest | FastEmbed ONNX + SQLite + Markdown File IO | 13.50 ms | 21.47 ms | ~75 notes/s |
| Neural Recall | Query Embedding + Dot Product + Keyword RRF | 13.71 ms | 14.79 ms | ~73 queries/s |
| Keyword FTS Search | SQLite FTS5 / PostgreSQL GIN tsvector | 0.99 ms | 1.24 ms | ~1,010 queries/s |
| Graph Traversal | Recursive CTE / In-Memory Wikilink Walk | 0.83 ms | 0.97 ms | ~1,200 walks/s |
| Context Assembler | Top-K Recall + Token Budgeting + XML Packing | 6.12 ms | 6.45 ms | ~163 assemblies/s |
Gomaa maintains a comprehensive automated test suite spanning 28 test modules:
collected 94 items
tests/test_adapters.py .. [ 2%]
tests/test_assemble_context.py ... [ 5%]
tests/test_chunking.py . [ 6%]
tests/test_cli_init.py .. [ 8%]
tests/test_compat.py .... [ 12%]
tests/test_consolidation.py .. [ 14%]
tests/test_dashboard.py ...... [ 21%]
tests/test_embedder.py ... [ 24%]
tests/test_embedder_offline.py . [ 25%]
tests/test_embedder_v32.py .. [ 27%]
tests/test_fts_websearch.py . [ 28%]
tests/test_gdrive_safe_path.py ..... [ 34%]
tests/test_gdrive_sync.py ... [ 37%]
tests/test_graph_cycles.py . [ 38%]
tests/test_injection_defense.py ... [ 41%]
tests/test_integration.py ... [ 44%]
tests/test_mcp.py .. [ 46%]
tests/test_mcp_edge_cases.py .. [ 48%]
tests/test_mcp_server.py .............. [ 63%]
tests/test_reconcile_links.py . [ 64%]
tests/test_remind_me_sqlite.py .... [ 69%]
tests/test_security.py ...... [ 75%]
tests/test_security_expanded.py ..... [ 80%]
tests/test_shared_memory.py .. [ 82%]
tests/test_sqlite.py ..... [ 88%]
tests/test_store_factory.py ... [ 91%]
tests/test_vault.py ..... [ 96%]
tests/test_vault_security.py ... [100%]
======================= 94 passed, 41 warnings in 13.38s =======================
# 1. Run all unit & integration tests locally (Light Mode with SQLite)
uv run pytest tests/ -v
# 2. Run with coverage report
uv run pytest tests/ --cov=gomaa --cov-report=term-missing
# 3. Run full test suite including live PostgreSQL + pgvector tests
MEMORY_DB_DSN="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}" uv run pytest tests/ -v
tmp_path) to generate ephemeral Obsidian vaults and SQLite databases, ensuring zero state pollution between runs..note.pid.tmp) are cleaned up immediately.tests/test_injection_defense.py and tests/test_security.py continuously verify that LLM control tokens, DAN mode overrides, path traversal attempts, and credential leaks are neutralized.Apache-2.0 License. Built for the open autonomous agent ecosystem. See LICENSE for full details.
Python
80.9%
HTML
15.2%
Shell
3.2%