# Engram

> Scope-aware memory architecture for multi-agent AI assistants. Powered by Mem0 + Qdrant + MCP.

- **Type:** MCP server
- **Install:** `agentstack add mcp-lofder-engram`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [lofder](https://agentstack.voostack.com/s/lofder)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [lofder](https://github.com/lofder)
- **Source:** https://github.com/lofder/Engram

## Install

```sh
agentstack add mcp-lofder-engram
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Engram

**Conquer your AI with personality, not a rulebook. 以德服 AI。**

[](LICENSE)
[](https://modelcontextprotocol.io)
[](https://mem0.ai)
[](https://qdrant.tech)

*An engram is the trace a memory leaves in the brain. This project does the same for AI — memory that persists across sessions, stays organized, and cleans up after itself.*

---

  English &nbsp;|&nbsp; 中文

English

## Why Engram?

You've had this experience: you spend 20 minutes explaining your project setup, coding style, or preferences to an AI assistant. It does exactly what you want. Next morning, new session — it knows nothing. You start over.

So you try the workaround: write it all down in a markdown file. `.cursor/rules`, `AGENTS.md`, a system prompt doc — whatever your tool calls it. It works at first. But then:

- The file keeps growing. Every time the AI gets something wrong, you add another rule.
- Old instructions conflict with new ones, and you have to go back and reconcile.
- You realize you're spending more time **maintaining the AI's memory** than doing actual work.
- You have multiple projects, multiple agents — and now multiple files to keep in sync.

You've become a full-time memory manager for your AI. That's backwards.

The deeper problem isn't just "AI forgets." It's that **the burden of remembering falls entirely on you.** You're manually doing what memory should do automatically: deciding what matters, updating when things change, and throwing out what's stale.

Engram flips this. Instead of you maintaining files for the AI, the AI maintains its own memory — structured, scoped, and self-cleaning. It decides what to keep, compresses old information, and forgets what's no longer relevant. You just use it.

```
Today:     You write rules.md → AI reads it → you update rules.md → repeat forever
Engram:    AI remembers on its own → compresses over time → you never maintain a file again
```

## Design Philosophy

### 1. Let the AI manage its own memory

You don't manually save bookmarks for every webpage you visit. Your brain decides what's worth remembering. Engram works the same way — the AI decides what to store, when to recall, and what to ignore. You just use it naturally; memory happens in the background.

### 2. Less is more

Returning 50 old memories into every conversation doesn't help — it wastes tokens and confuses the model. Engram keeps memory lean: duplicates are merged, old logs get summarized into compact knowledge, and stale entries fade away automatically. The result is a small, high-quality set of memories that actually improve responses.

### 3. Important things should last

Not all memories are equal. Your preferences ("always use TypeScript"), lessons learned ("that API has a 5-second timeout"), and key decisions ("we're using PostgreSQL") should never be forgotten. But yesterday's deployment log? That can fade — after being distilled into lasting knowledge first.

## MCP Tools

Engram exposes **5 tools** via the MCP protocol. Any MCP-compatible client (Cursor, Claude Desktop, custom agents) can call them:

### `mem0_add` — Store a memory

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | **yes** | The memory text |
| `scope` | string | **yes** | `global`, `group:xxx`, `dm`, `agent:xxx` |
| `mem_type` | string | no | `preference`, `fact`, `procedure`, `lesson`, `decision`, `task_log`, `knowledge` |
| `source` | string | no | `user_direct`, `agent_output`, `tool_result`, `inferred` (default: `agent_output`) |
| `trust` | string | no | `high`, `medium`, `low` (default: `medium`) |
| `context` | string | no | Additional context for retrieval |
| `agent` | string | no | Caller identity for permission check |

**Returns**: `{"results": [...]}` on success, `{"queued": true, "write_id": "..."}` if Mem0 is down (auto-replayed later), `{"error": "..."}` on permission/safety violation.

**Guards**: permission check → never_store regex → scope validation → write (or queue).

### `mem0_search` — Dual-query search

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `query` | string | **yes** | Natural language search query |
| `scope` | string | no | Target scope (default: `global`). Use `cross:group_id` for cross-scope |
| `mem_type` | string | no | Filter by memory type |
| `trust_min` | string | no | Minimum trust level: `high`, `medium`, `low` |
| `limit` | int | no | Max results (default: 5) |
| `agent` | string | no | Caller identity |

**How dual-query works**: When scope is `group:xxx`, Engram runs two parallel searches (group + global), then interleaves results by relevance. You always get the best of both local and global context in one call.

**Returns**: Array of memory objects with `content`, `metadata` (scope, trust, mem_type, source, agent, access_count), sorted by relevance then trust.

### `mem0_get_all` — Full inventory

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | string | no | User filter (default: `default`) |
| `scope` | string | no | Scope filter |
| `agent` | string | no | Caller identity |

**Returns**: `{"total": N, "results": [...]}` — all active (non-archived) memories matching the filter.

### `mem0_status` — Health check

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `agent` | string | no | Caller identity |

**Returns**: Full system health including:
- `mem0_ready` / `qdrant_ready` — backend status
- `total_memories` / `active_memories` / `archived_memories`
- `by_scope` — count per scope
- `by_type` — count per memory type
- `by_trust` — count per trust level
- `write_queue_size` — pending offline writes
- `embedding_model` / `config_version` / `schema_version`

### `mem0_maintenance` — Maintenance report

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `mode` | string | no | `report_only` (default: `daily`). `daily`/`weekly` are placeholders — run via CLI |
| `agent` | string | no | Caller identity (needs main/devops permission) |

**Note**: The MCP tool generates reports. Actual maintenance (Opus re-extraction, dedup, consolidation, decay) runs via `python src/maintenance.py` scheduled through cron.

## Architecture

### System layers

```
┌─────────────────────────────────────────────────────────────────┐
│  L1: Agent Layer                                                │
│                                                                 │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │   Main   │  │  Worker  │  │  Worker  │  │  DevOps  │       │
│  │  Agent   │  │  Agent A │  │  Agent B │  │  Agent   │       │
│  │          │  │          │  │          │  │          │       │
│  │ r: all   │  │ r: —     │  │ r: —     │  │ r: all   │       │
│  │ w: global│  │ w: self  │  │ w: self  │  │ w: all   │       │
│  │   group  │  │          │  │          │  │          │       │
│  │   dm     │  │          │  │          │  │          │       │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘       │
│       │              │              │              │             │
└───────┼──────────────┼──────────────┼──────────────┼─────────────┘
        │              │              │              │
        └──────────────┴──────┬───────┴──────────────┘
                              │ MCP (stdio)
┌─────────────────────────────┼───────────────────────────────────┐
│  L2: Engram MCP Server      ▼                                   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                     5 MCP Tools                          │   │
│  │  mem0_add · mem0_search · mem0_get_all                   │   │
│  │  mem0_status · mem0_maintenance                          │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│  ┌─────────────┐  ┌─────────┴──────────┐  ┌────────────────┐  │
│  │ Permission  │  │   Write Pipeline   │  │  never_store   │  │
│  │ Enforcer    │  │                    │  │  Regex Guard   │  │
│  │             │  │  infer=False       │  │                │  │
│  │ per-agent   │  │  (embedding only,  │  │  blocks keys,  │  │
│  │ read/write  │  │   no LLM call)     │  │  passwords,    │  │
│  │ scope rules │  │                    │  │  tokens        │  │
│  └─────────────┘  │  on failure:       │  └────────────────┘  │
│                   │  → write_queue     │                       │
│                   │    (auto-replay)   │                       │
│                   └────────┬───────────┘                       │
│                            │                                    │
└────────────────────────────┼────────────────────────────────────┘
                             │
        ┌────────────────────┼────────────────────┐
        │                    │                    │
        ▼                    ▼                    ▼
┌──────────────┐    ┌──────────────┐    ┌──────────────────────┐
│   Mem0 SDK   │    │   Qdrant     │    │   Maintenance CLI    │
│              │    │   Server     │    │                      │
│  embedding + │    │              │    │  Daily (3 AM):       │
│  vector write│    │  persistent  │    │  · Opus re-extract   │
│              │    │  vector      │    │  · Vector dedup      │
│  primary:    │    │  storage     │    │                      │
│   Gemini     │    │              │    │  Weekly (Sun 4 AM):  │
│  fallback:   │    │  payload     │    │  · Conflict detect   │
│   OpenAI API │    │  metadata    │    │  · Consolidation     │
│              │    │  filtering   │    │  · Bjork decay       │
└──────────────┘    └──────────────┘    └──────────────────────┘
```

### Data flow: write

```
Agent calls mem0_add("User prefers dark mode", scope="global", mem_type="preference")
  │
  ├─ Permission check: does this agent have write access to "global"?
  ├─ never_store check: does content match any sensitive pattern?
  ├─ Scope validation: is this a writable scope?
  │
  ▼
  Mem0.add(content, metadata={scope, trust, mem_type, source, agent, ...}, infer=False)
  │
  ├─ Success → return result
  └─ Failure → append to write_queue.jsonl → auto-replay on next successful call
```

### Data flow: search

```
Agent calls mem0_search("user preferences", scope="group:team_alpha")
  │
  ├─ Permission check: can this agent read "group:team_alpha"?
  │
  ▼
  Two parallel searches:
  ├─ Search 1: scope="group:team_alpha", archived=false
  └─ Search 2: scope="global", archived=false
  │
  ▼
  Interleave by relevance → trust_min filter → limit → bump access_count (async)
  │
  ▼
  Return: [{content, metadata: {scope, trust, mem_type, ...}}, ...]
```

### Memory lifecycle

| Type | Decay | Lifespan | Purpose |
|------|-------|----------|---------|
| `preference` | **Never** | Permanent | "User prefers dark mode" |
| `fact` | **Never** | Permanent | "Project uses PostgreSQL 16" |
| `lesson` | **Never** | Permanent | "Don't use recursive CTE for this table" |
| `decision` | **Never** | Permanent | "We chose React over Vue for the dashboard" |
| `knowledge` | **Never** | Permanent | Consolidated from task_logs |
| `procedure` | 90-day half-life | Months | "Deploy command: `kubectl apply -f ...`" |
| `task_log` | 30-day half-life | Weeks | "Deployed v2.3 to staging" → consolidates before decay |

### Maintenance pipeline

```
                    ┌─────────┐
                    │  Cron   │
                    └────┬────┘
                         │
              ┌──────────┼──────────┐
              ▼                     ▼
     ┌────────────────┐    ┌────────────────┐
     │  Daily (3 AM)  │    │ Weekly (Sun 4) │
     │                │    │                │
     │ 1. Opus re-    │    │ 1. Everything  │
     │    extract     │    │    from daily  │
     │    today's     │    │                │
     │    memories    │    │ 2. Conflict    │
     │                │    │    detection   │
     │ 2. Vector      │    │    (same-scope │
     │    dedup       │    │     fact vs    │
     │    (≥0.92      │    │     fact)      │
     │     cosine)    │    │                │
     │                │    │ 3. Consolidate │
     │ 3. Report      │    │    (N task_log │
     │                │    │     → 1        │
     └────────────────┘    │     knowledge) │
                           │                │
                           │ 4. Bjork decay │
                           │    importance  │
                           │    

中文

## 为什么需要 Engram？

你一定有过这样的体验：花了 20 分钟跟 AI 助手解释你的项目结构、编码风格、个人偏好。它干得漂亮。第二天，新会话——它什么都不记得了。你只能从头再来。

于是你想了个办法：写个 md 文件。`.cursor/rules`、`AGENTS.md`、系统 prompt 文档——叫什么都行。一开始挺好用。但慢慢地：

- 文件越写越长。每次 AI 搞错什么，你就加一条规则。
- 旧指令和新指令打架，你得回去手动理顺。
- 你发现自己花在**维护 AI 的记忆**上的时间比干正事还多。
- 你有多个项目、多个 Agent——现在还得同步多个文件。

你变成了 AI 的全职记忆管理员。这完全搞反了。

更深层的问题不只是"AI 会忘"，而是**记忆的负担全压在你身上。** 你在手动做记忆系统该自动做的事：判断什么重要、变化时更新、过时了就清掉。

Engram 把这件事翻转过来。不是你替 AI 维护文件，而是 AI 自己维护自己的记忆——结构化的、分域的、能自我清理的。它自己判断什么该留，自动压缩旧信息，自动淡出不再相关的内容。你只管用。

```
现在:     你写 rules.md → AI 读它 → 你更新 rules.md → 无限循环
Engram:   AI 自己记住 → 随时间压缩 → 你再也不用维护文件了
```

## 设计理念

### 1. 让 AI 管理自己的记忆

你不会手动给每个打开过的网页存书签，你的大脑会自己判断什么值得记住。Engram 同理——AI 自己决定存什么、何时回忆、忽略什么。你只管正常使用，记忆在后台自然发生。

### 2. 少即是多

每次对话塞进去 50 条旧记忆并没有帮助——只会浪费 token 和干扰模型。Engram 让记忆保持精简：重复的合并、旧日志浓缩成简洁的知识、过时的条目自动淡出。最终结果是一组小而高质量的记忆，真正能改善回复质量。

### 3. 重要的东西应该持久

不是所有记忆都同等重要。你的偏好（"永远用 TypeScript"）、学到的教训（"那个 API 有 5 秒超时"）、关键决策（"我们用 PostgreSQL"）——这些永远不该被忘记。但昨天的部署日志？它可以慢慢淡出——在被提炼成持久知识之后。

## MCP 工具

Engram 通过 MCP 协议暴露 **5 个工具**。任何 MCP 兼容客户端（Cursor、Claude Desktop、自定义 Agent）都可以调用：

### `mem0_add` — 存储记忆

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `content` | string | **是** | 记忆内容 |
| `scope` | string | **是** | `global`、`group:xxx`、`dm`、`agent:xxx` |
| `mem_type` | string | 否 | `preference`、`fact`、`procedure`、`lesson`、`decision`、`task_log`、`knowledge` |
| `source` | string | 否 | `user_direct`、`agent_output`、`tool_result`、`inferred`（默认：`agent_output`） |
| `trust` | string | 否 | `high`、`medium`、`low`（默认：`medium`） |
| `context` | string | 否 | 辅助检索的附加上下文 |
| `agent` | string | 否 | 调用者身份，用于权限校验 |

**返回**：成功 `{"results": [...]}`，Mem0 不可用时 `{"queued": true, "write_id": "..."}`（后续自动重放），权限/安全违规 `{"error": "..."}`。

### `mem0_search` — 双路检索

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `query` | string | **是** | 自然语言搜索 |
| `scope` | string | 否 | 目标 scope（默认：`global`）。用 `cross:group_id` 跨域搜索 |
| `mem_type` | string | 否 | 按记忆类型过滤 |
| `trust_min` | string | 否 | 最低信任等级：`high`、`medium`、`low` |
| `limit` | int | 否 | 最大返回数（默认：5） |
| `agent` | string | 否 | 调用者身份 |

**双路合并**：当 scope 是 `group:xxx` 时，Engram 并行搜索（group + global），按相关性交错合并。一次调用同时获得本地和全局最佳结果。

### `mem0_get_all` — 全量列举

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `user_id` | string | 否 | 用户过滤（默认：`default`） |
| `scope` | string | 否 | scope 过滤 |
| `agent` | string | 否 | 调用者身份 |

### `mem0_status` — 健康检查

返回完整系统状态：后端就绪性、记忆总数/活跃数/归档数、按 scope/类型/信任等级的分布、写入队列大小、embedding 模型版本。

### `mem0_maintenance` — 维护报告

MCP 工具提供报告查看。实际维护（Opus 重提取、去重、巩固、衰减）通过 `python src/maintenance.py` 由 cron 调度执行。

## 架构

### 系统分层

```
┌─────────────────────────────────────────────────────────────────┐
│  L1: Agent 层                                                    │
│                                                                 │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐       │
│  │  Main    │  │ Worker A │  │ Worker B │  │  DevOps  │       │
│  │  Agent   │  │          │  │          │  │  Agent   │       │
│  │          │  │          │  │          │  │          │       │
│  │ 读: 全域  │  │ 读: —    │  │ 读: —    │  │ 读: 全域  │       │
│  │ 写: global│  │ 写: self │  │ 写: self │  │ 写: 全域  │       │
│  │   group  │  │          │  │          │  │          │       │
│  │   dm     │  │          │  │          │  │          │       │
│  └────┬─────┘  └────┬─────┘  └

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [lofder](https://github.com/lofder)
- **Source:** [lofder/Engram](https://github.com/lofder/Engram)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-lofder-engram
- Seller: https://agentstack.voostack.com/s/lofder
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
