hmem-mcp 3.9.0 → 3.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -415
- package/dist/hmem-store.js +18 -1
- package/dist/hmem-store.js.map +1 -1
- package/dist/mcp-server.js +19 -6
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,204 +1,154 @@
|
|
|
1
1
|
# hmem — Humanlike Memory for AI Agents
|
|
2
2
|
|
|
3
|
-
> AI
|
|
3
|
+
> **Your AI loads 5k tokens and has full context of 400k+.** That's hmem — persistent, hierarchical memory that works across sessions, devices, and AI tools. Zero tokens wasted.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**hmem** is an MCP server that gives AI agents human-like long-term memory. Instead of dumping everything into context, it stores knowledge in a 5-level hierarchy — like how you remember: broad strokes first, details on demand.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Born as a side project of a multi-agent AI system, hmem solves a real problem: when you work across multiple machines or sessions, your AI instances start from zero every time. They duplicate work, contradict previous decisions, and lose hard-won context.
|
|
10
|
-
|
|
11
|
-
**hmem fixes this.**
|
|
7
|
+
The result? An AI that starts a new session and *already knows* your projects, your decisions, your past mistakes, your preferences — across your laptop, your PC, and your server. Simultaneously.
|
|
12
8
|
|
|
13
9
|
---
|
|
14
10
|
|
|
11
|
+
## Why hmem?
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<img width="1110" height="665" alt="image" src="https://github.com/user-attachments/assets/af7688d2-73e3-44f8-b414-f6afa8904e6c" />
|
|
19
|
-
Well, it claims that it can't pinpoint timestamps. But that's not true. It just cant see them (due to token efficiency) :)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<img width="1096" height="941" alt="image" src="https://github.com/user-attachments/assets/a751c8f3-41fc-46b6-916a-bcd3862008ad" />
|
|
13
|
+
**Without hmem:** Every session starts from zero. Your AI asks the same questions, makes the same mistakes, contradicts last week's decisions, and wastes tokens loading context it already processed.
|
|
23
14
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Existing RAG solutions are flat — every memory fragment has the same abstraction level. The agent either gets too much detail and wastes tokens, or too little and loses nuance.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## The Solution: 5-Level Humanlike Memory
|
|
36
|
-
|
|
37
|
-
hmem stores and retrieves memory in five nested levels of detail — mirroring how human memory works.
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
Level 1 ── Coarse summary (always loaded on spawn)
|
|
41
|
-
Level 2 ── More detail
|
|
42
|
-
Level 3 ── Deep context
|
|
43
|
-
Level 4 ── Fine-grained specifics
|
|
44
|
-
Level 5 ── Full verbatim detail
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
A freshly spawned agent receives only Level 1 — the broadest strokes. When it needs more detail on a specific topic, it makes a tool call to retrieve Level 2 for that entry. And so on, down to full detail.
|
|
48
|
-
|
|
49
|
-
**Result: Agents load exactly as much context as they need — no more, no less.**
|
|
15
|
+
**With hmem:**
|
|
16
|
+
- **5k tokens** loads a complete overview of 300+ memories spanning months of work
|
|
17
|
+
- **Drill on demand** — the AI only fetches details when it actually needs them
|
|
18
|
+
- **Cross-device** — encrypted sync means your laptop, PC, and server share the same brain
|
|
19
|
+
- **Cross-tool** — works with Claude Code, Gemini CLI, Cursor, Windsurf, OpenCode, Cline
|
|
20
|
+
- **Auto-logging** — via Claude Code's Stop hook, every conversation is automatically preserved
|
|
21
|
+
- **No token waste** — hierarchical lazy loading means the AI never loads more than it needs
|
|
50
22
|
|
|
51
23
|
---
|
|
52
24
|
|
|
53
25
|
## How It Works
|
|
54
26
|
|
|
55
|
-
<img width="693" height="715" alt="image" src="https://github.com/user-attachments/assets/9dcb382a-6567-4040-99d2-61916a6d7531" />
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### Saving Memory
|
|
59
|
-
|
|
60
|
-
After completing a task, an agent calls `write_memory` with tab-indented content. The indentation depth maps to memory levels — multiple entries at the same depth become siblings.
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
write_memory(prefix="L", content="Always restart MCP server after recompiling TypeScript
|
|
64
|
-
Running process holds old dist — tool calls return stale results
|
|
65
|
-
Fix: kill $(pgrep -f mcp-server)")
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Loading Memory
|
|
69
|
-
|
|
70
|
-
On spawn, the agent receives all Level 1 summaries. Deeper levels are fetched on demand — by ID, one branch at a time.
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
read_memory() # → all L1 summaries
|
|
74
|
-
read_memory(id="L0003") # → L1 + direct L2 children for this entry
|
|
75
|
-
read_memory(id="L0003.2") # → that L2 node + its L3 children
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Each node gets a compound ID (`L0003.2.1`) so any branch is individually addressable.
|
|
79
|
-
|
|
80
|
-
### Updating Memory
|
|
81
|
-
|
|
82
|
-
Entries can be updated without deleting and recreating them:
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
update_memory(id="L0003", content="Corrected L1 summary") # update text
|
|
86
|
-
update_memory(id="L0003", favorite=true) # toggle flag only
|
|
87
|
-
update_memory(id="L0003.2", content="Fixed sub-node text") # fix a sub-node
|
|
88
|
-
append_memory(id="L0003", content="New finding\n\tSub-detail")
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
`update_memory` replaces the text of a single node (children preserved). Content is optional — pass only flags to toggle them without repeating the text. `append_memory` adds new child nodes to an existing entry.
|
|
92
|
-
|
|
93
|
-
### Obsolete Entries
|
|
94
|
-
|
|
95
|
-
When an entry is outdated, mark it as obsolete — never delete it:
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
update_memory(id="E0023", content="...", obsolete=true)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Obsolete entries are **hidden from bulk reads** and replaced by a summary line at the bottom:
|
|
102
|
-
|
|
103
27
|
```
|
|
104
|
-
|
|
28
|
+
Level 1 ── One-line summary (always loaded — ~5k tokens for 300 entries)
|
|
29
|
+
Level 2 ── Paragraph detail (loaded on demand)
|
|
30
|
+
Level 3 ── Full context (loaded on demand)
|
|
31
|
+
Level 4 ── Extended detail (loaded on demand)
|
|
32
|
+
Level 5 ── Raw/verbatim data (loaded on demand)
|
|
105
33
|
```
|
|
106
34
|
|
|
107
|
-
|
|
35
|
+
At session start, the agent loads Level 1 summaries — one line per memory. When it needs more detail on a specific topic, it drills down: `read_memory(id="L0042")` loads that entry's Level 2 children. And so on.
|
|
108
36
|
|
|
109
|
-
|
|
37
|
+
**Categories keep things organized:**
|
|
110
38
|
|
|
111
|
-
|
|
39
|
+
| Prefix | Category | Example |
|
|
40
|
+
|--------|----------|---------|
|
|
41
|
+
| P | Project | `hmem-mcp \| Active \| TS/SQLite/npm \| Persistent hierarchical AI memory` |
|
|
42
|
+
| L | Lesson | `Always restart MCP server after recompiling TypeScript` |
|
|
43
|
+
| E | Error | `hmem-sync Schema-Drift: access_count missing after pull` |
|
|
44
|
+
| D | Decision | `Per-node tag scoring instead of union-set for related discovery` |
|
|
45
|
+
| H | Human | `User Skill: IT — TypeScript: 3, Architecture: 9, AHK: 9` |
|
|
46
|
+
| R | Rule | `Max one npm publish per day — batch changes` |
|
|
47
|
+
| I | Infrastructure | `Strato Server \| Active \| Linux \| 4 cores, 8GB RAM` |
|
|
48
|
+
| T | Task | `Config consolidation: merge 6 files into 1` |
|
|
49
|
+
| O | Original | Auto-recorded raw conversation history (via Stop hook) |
|
|
112
50
|
|
|
113
51
|
---
|
|
114
52
|
|
|
115
53
|
## Key Features
|
|
116
54
|
|
|
117
|
-
- **
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
120
|
-
-
|
|
121
|
-
- **
|
|
122
|
-
- **
|
|
123
|
-
- **
|
|
124
|
-
- **
|
|
125
|
-
- **
|
|
126
|
-
- **
|
|
127
|
-
- **
|
|
128
|
-
- **
|
|
129
|
-
- **
|
|
130
|
-
- **Secret entries** — `[s]` entries/nodes excluded from `export_memory`
|
|
131
|
-
- **Titles & compact views** — auto-extracted titles; `titles_only` mode for table-of-contents view
|
|
132
|
-
- **Effective-date sorting** — entries with recent appends surface to the top
|
|
133
|
-
- **Per-agent memory** — each agent has its own `.hmem` file (SQLite)
|
|
134
|
-
- **Skill-file driven** — agents are instructed via skill files, no hardcoded logic
|
|
135
|
-
- **MCP-native** — works with Claude Code, Gemini CLI, OpenCode, and any MCP-compatible tool
|
|
55
|
+
- **5-level lazy loading** — tokens scale with need, not with total memory size
|
|
56
|
+
- **Smart bulk reads** — V2 algorithm expands newest, most-accessed, and favorites; suppresses the rest to titles
|
|
57
|
+
- **Project-aware filtering** — activate a project, and only relevant memories are expanded; others show title-only
|
|
58
|
+
- **`#universal` tag** — cross-project knowledge (MCP patterns, deployment rules) always shown regardless of active project
|
|
59
|
+
- **Duplicate detection** — `write_memory` warns if similar entries exist (tag overlap + FTS5 title similarity)
|
|
60
|
+
- **Encrypted sync** — AES-256-GCM client-side encryption, zero-knowledge server, multi-server redundancy
|
|
61
|
+
- **Auto-logging** — Claude Code Stop hook records every conversation automatically (O-prefix)
|
|
62
|
+
- **Announcements** — broadcast urgent messages to all synced devices (server migration, config changes)
|
|
63
|
+
- **User skill assessment** — agents silently track your expertise per topic (1-10 scale) and adapt communication
|
|
64
|
+
- **Hashtags** — cross-cutting tags for filtering and related-entry discovery
|
|
65
|
+
- **Obsolete chains** — mark entries wrong with `[✓ID]` correction reference; auto-follows to current version
|
|
66
|
+
- **Import/Export** — share memories between agents or back up as Markdown
|
|
67
|
+
- **Multi-agent routing** — `route_task` scores all agent memory stores to find the best agent for a task
|
|
136
68
|
|
|
137
69
|
---
|
|
138
70
|
|
|
139
|
-
##
|
|
71
|
+
## Installation
|
|
140
72
|
|
|
141
|
-
###
|
|
73
|
+
### Step 1: Install the package
|
|
142
74
|
|
|
143
75
|
```bash
|
|
144
|
-
|
|
76
|
+
npm install -g hmem-mcp
|
|
145
77
|
```
|
|
146
78
|
|
|
147
|
-
|
|
148
|
-
- Detect your installed AI coding tools (Claude Code, OpenCode, Cursor, Windsurf, Cline)
|
|
149
|
-
- Ask whether to install **system-wide** (memories in `~/.hmem/`) or **project-local** (memories in current directory)
|
|
150
|
-
- **Offer an example memory** with 67 real entries from hmem development — or start fresh
|
|
151
|
-
- Configure each tool's MCP settings automatically
|
|
152
|
-
- Create the memory directory and `hmem.config.json`
|
|
79
|
+
Skills are **automatically copied** to detected AI tools (Claude Code, OpenCode, Gemini CLI) via postinstall hook.
|
|
153
80
|
|
|
154
|
-
|
|
81
|
+
### Step 2: Configure your MCP client
|
|
155
82
|
|
|
156
|
-
|
|
83
|
+
**IMPORTANT:** Do NOT use `claude mcp add` — it misplaces environment variables. Configure manually:
|
|
157
84
|
|
|
158
|
-
|
|
159
|
-
>
|
|
160
|
-
> **Coming from the MCP Registry?** Run `npx hmem-mcp init` first — it configures your tools and creates the memory directory. Then copy the skill files as described below.
|
|
85
|
+
#### Claude Code
|
|
161
86
|
|
|
162
|
-
|
|
87
|
+
Edit `~/.claude/.mcp.json` (create if it doesn't exist):
|
|
163
88
|
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
node
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"mcpServers": {
|
|
92
|
+
"hmem": {
|
|
93
|
+
"command": "node",
|
|
94
|
+
"args": ["/path/to/hmem-mcp/dist/mcp-server.js"],
|
|
95
|
+
"env": {
|
|
96
|
+
"HMEM_PROJECT_DIR": "/home/yourname/.hmem"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
169
101
|
```
|
|
170
102
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
#### 1. Install
|
|
103
|
+
**Find the path** to `mcp-server.js`:
|
|
104
|
+
```bash
|
|
105
|
+
echo "$(npm root -g)/hmem-mcp/dist/mcp-server.js"
|
|
106
|
+
```
|
|
176
107
|
|
|
108
|
+
**nvm users:** Use the absolute path to `node` instead of just `"node"`:
|
|
177
109
|
```bash
|
|
178
|
-
|
|
110
|
+
echo "$(which node)"
|
|
111
|
+
# e.g. /home/yourname/.nvm/versions/node/v24.14.0/bin/node
|
|
179
112
|
```
|
|
180
113
|
|
|
181
|
-
|
|
114
|
+
Then use that as the `"command"` value.
|
|
182
115
|
|
|
183
|
-
####
|
|
116
|
+
#### With agent ID (multi-agent setups)
|
|
184
117
|
|
|
185
|
-
|
|
118
|
+
If you use `HMEM_AGENT_ID`, the database path changes:
|
|
186
119
|
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
|
|
120
|
+
```
|
|
121
|
+
Without HMEM_AGENT_ID: {HMEM_PROJECT_DIR}/memory.hmem
|
|
122
|
+
With HMEM_AGENT_ID=X: {HMEM_PROJECT_DIR}/Agents/X/X.hmem
|
|
190
123
|
```
|
|
191
124
|
|
|
192
|
-
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"mcpServers": {
|
|
128
|
+
"hmem": {
|
|
129
|
+
"command": "/absolute/path/to/node",
|
|
130
|
+
"args": ["/absolute/path/to/hmem-mcp/dist/mcp-server.js"],
|
|
131
|
+
"env": {
|
|
132
|
+
"HMEM_PROJECT_DIR": "/home/yourname/.hmem",
|
|
133
|
+
"HMEM_AGENT_ID": "DEVELOPER"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### OpenCode
|
|
141
|
+
|
|
142
|
+
Edit `~/.config/opencode/opencode.json`:
|
|
193
143
|
|
|
194
144
|
```json
|
|
195
145
|
{
|
|
196
146
|
"mcp": {
|
|
197
147
|
"hmem": {
|
|
198
148
|
"type": "local",
|
|
199
|
-
"command": ["
|
|
149
|
+
"command": ["/absolute/path/to/node", "/absolute/path/to/hmem-mcp/dist/mcp-server.js"],
|
|
200
150
|
"environment": {
|
|
201
|
-
"HMEM_PROJECT_DIR": "
|
|
151
|
+
"HMEM_PROJECT_DIR": "/home/yourname/.hmem"
|
|
202
152
|
},
|
|
203
153
|
"enabled": true
|
|
204
154
|
}
|
|
@@ -206,352 +156,183 @@ claude mcp add hmem -s user -- npx hmem-mcp serve \
|
|
|
206
156
|
}
|
|
207
157
|
```
|
|
208
158
|
|
|
209
|
-
|
|
159
|
+
#### Cursor / Windsurf / Cline
|
|
160
|
+
|
|
161
|
+
Edit the respective MCP config file (`~/.cursor/mcp.json`, `~/.codeium/windsurf/mcp_config.json`, or `.vscode/mcp.json`):
|
|
210
162
|
|
|
211
163
|
```json
|
|
212
164
|
{
|
|
213
165
|
"mcpServers": {
|
|
214
166
|
"hmem": {
|
|
215
|
-
"command": "
|
|
216
|
-
"args": ["hmem"
|
|
167
|
+
"command": "/absolute/path/to/node",
|
|
168
|
+
"args": ["/absolute/path/to/hmem-mcp/dist/mcp-server.js"],
|
|
217
169
|
"env": {
|
|
218
|
-
"HMEM_PROJECT_DIR": "
|
|
170
|
+
"HMEM_PROJECT_DIR": "/home/yourname/.hmem"
|
|
219
171
|
}
|
|
220
172
|
}
|
|
221
173
|
}
|
|
222
174
|
}
|
|
223
175
|
```
|
|
224
176
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
#### 3. Verify the connection
|
|
228
|
-
|
|
229
|
-
Fully restart your AI tool, then call `read_memory()`. You should see a memory listing (empty on first run is fine).
|
|
230
|
-
|
|
231
|
-
In Claude Code, run `/mcp` to check the server status.
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
## Skill Files
|
|
236
|
-
|
|
237
|
-
Skill files teach your AI tool how to use hmem correctly. Copy them to your tool's global skills directory, then restart your AI tool.
|
|
238
|
-
|
|
239
|
-
> **After copying skills, fully restart your terminal and AI tool** — skills are loaded at startup and won't appear in a running session.
|
|
240
|
-
|
|
241
|
-
### Available skills
|
|
242
|
-
|
|
243
|
-
| Slash command | What it does |
|
|
244
|
-
|---|---|
|
|
245
|
-
| `/hmem-read` | Load your memory at session start — call at the beginning of every session |
|
|
246
|
-
| `/hmem-write` | Protocol for writing memories correctly (prefixes, hierarchy, anti-patterns) |
|
|
247
|
-
| `/hmem-save` | Save session learnings to memory, then commit + push |
|
|
248
|
-
| `/hmem-config` | View and adjust memory settings (`hmem.config.json`) interactively |
|
|
249
|
-
| `/hmem-curate` | Audit and clean up memory entries (curator role required) |
|
|
250
|
-
|
|
251
|
-
### Copy skills to your tool
|
|
252
|
-
|
|
253
|
-
Find the skills directory in the installed package:
|
|
177
|
+
### Step 3: Create the memory directory
|
|
254
178
|
|
|
255
179
|
```bash
|
|
256
|
-
|
|
180
|
+
mkdir -p ~/.hmem
|
|
181
|
+
# Or with agent ID:
|
|
182
|
+
mkdir -p ~/.hmem/Agents/DEVELOPER
|
|
257
183
|
```
|
|
258
184
|
|
|
259
|
-
|
|
185
|
+
### Step 4: Restart and verify
|
|
260
186
|
|
|
261
|
-
|
|
262
|
-
```bash
|
|
263
|
-
for skill in hmem-read hmem-write hmem-save hmem-config hmem-curate; do
|
|
264
|
-
mkdir -p ~/.claude/skills/$skill
|
|
265
|
-
cp "$HMEM_DIR/skills/$skill/SKILL.md" ~/.claude/skills/$skill/SKILL.md
|
|
266
|
-
done
|
|
267
|
-
```
|
|
187
|
+
Restart your AI tool completely, then:
|
|
268
188
|
|
|
269
|
-
**Gemini CLI:**
|
|
270
|
-
```bash
|
|
271
|
-
for skill in hmem-read hmem-write hmem-save hmem-config hmem-curate; do
|
|
272
|
-
mkdir -p ~/.gemini/skills/$skill
|
|
273
|
-
cp "$HMEM_DIR/skills/$skill/SKILL.md" ~/.gemini/skills/$skill/SKILL.md
|
|
274
|
-
done
|
|
275
189
|
```
|
|
276
|
-
|
|
277
|
-
**OpenCode:**
|
|
278
|
-
```bash
|
|
279
|
-
for skill in hmem-read hmem-write hmem-save hmem-config hmem-curate; do
|
|
280
|
-
mkdir -p ~/.config/opencode/skills/$skill
|
|
281
|
-
cp "$HMEM_DIR/skills/$skill/SKILL.md" ~/.config/opencode/skills/$skill/SKILL.md
|
|
282
|
-
done
|
|
190
|
+
read_memory()
|
|
283
191
|
```
|
|
284
192
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
### Memory Tools
|
|
290
|
-
|
|
291
|
-
| Tool | Description |
|
|
292
|
-
|------|-------------|
|
|
293
|
-
| `read_memory` | Read memories — L1 summaries, drill by ID, filter by prefix, search by time |
|
|
294
|
-
| `write_memory` | Save new memory entries with tab-indented hierarchy |
|
|
295
|
-
| `update_memory` | Update text and/or flags of an entry or sub-node (content optional) |
|
|
296
|
-
| `append_memory` | Append new child nodes to an existing entry or sub-node |
|
|
297
|
-
| `export_memory` | Export non-secret entries as Markdown text or `.hmem` SQLite file |
|
|
298
|
-
| `import_memory` | Import entries from a `.hmem` file with deduplication and ID remapping |
|
|
299
|
-
| `reset_memory_cache` | Clear session cache so all entries are treated as unseen |
|
|
300
|
-
| `search_memory` | Full-text search across all agent `.hmem` databases |
|
|
301
|
-
| `memory_stats` | Overview: total entries by prefix, nodes, favorites, pinned, stale count, most-accessed |
|
|
302
|
-
| `find_related` | FTS5-based similarity search — find entries with overlapping keywords |
|
|
303
|
-
| `memory_health` | Audit report: broken links, orphaned entries, stale favorites, broken obsolete chains |
|
|
304
|
-
| `tag_bulk` | Apply tag changes (add/remove) to all entries matching a filter |
|
|
305
|
-
| `tag_rename` | Rename a hashtag across all entries and nodes |
|
|
306
|
-
| `move_memory` | Move a sub-node (+ entire subtree) to a different parent — updates all IDs and references |
|
|
307
|
-
|
|
308
|
-
### Curator Tools (role: ceo)
|
|
309
|
-
|
|
310
|
-
| Tool | Description |
|
|
311
|
-
|------|-------------|
|
|
312
|
-
| `get_audit_queue` | List agents whose memory has changed since last audit |
|
|
313
|
-
| `read_agent_memory` | Read any agent's full memory (for curation) |
|
|
314
|
-
| `fix_agent_memory` | Correct a specific entry or sub-node in any agent's memory |
|
|
315
|
-
| `append_agent_memory` | Add content to an existing entry in any agent's memory (for merging duplicates) |
|
|
316
|
-
| `delete_agent_memory` | Delete a memory entry (prefer `fix_agent_memory(obsolete=true)` — deletion is permanent) |
|
|
317
|
-
| `move_agent_memory` | Move a sub-node in any agent's memory to a different parent — updates all IDs and references |
|
|
318
|
-
| `mark_audited` | Mark an agent as audited |
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## Memory Directory
|
|
323
|
-
|
|
324
|
-
hmem stores all memory files (`.hmem` SQLite databases) and its configuration (`hmem.config.json`) in a single directory. The location depends on how you install:
|
|
325
|
-
|
|
326
|
-
| Install mode | Memory directory | Example |
|
|
327
|
-
|---|---|---|
|
|
328
|
-
| **System-wide** | `~/.hmem/` | `/home/alice/.hmem/` or `C:\Users\Alice\.hmem\` |
|
|
329
|
-
| **Project-local** | Project root (cwd) | `/home/alice/my-project/` |
|
|
330
|
-
|
|
331
|
-
The `hmem init` installer asks which mode you prefer and creates the directory automatically.
|
|
332
|
-
|
|
333
|
-
### Directory structure
|
|
193
|
+
You should see a response. If empty, that's fine — first run. If you get an error, check:
|
|
194
|
+
- Is `HMEM_PROJECT_DIR` an absolute path?
|
|
195
|
+
- Does the directory exist?
|
|
196
|
+
- Is `node` path correct? (nvm users: use absolute path)
|
|
334
197
|
|
|
198
|
+
The server logs its configuration on startup:
|
|
335
199
|
```
|
|
336
|
-
|
|
337
|
-
memory.hmem # Default agent memory (when no HMEM_AGENT_ID is set)
|
|
338
|
-
SIGURD.hmem # Named agent memory (HMEM_AGENT_ID=SIGURD)
|
|
339
|
-
hmem.config.json # Configuration file
|
|
340
|
-
audit_state.json # Curator state (optional)
|
|
200
|
+
[hmem:DEVELOPER] MCP Server running on stdio | Agent: DEVELOPER | DB: /home/you/.hmem/Agents/DEVELOPER/DEVELOPER.hmem (0 entries)
|
|
341
201
|
```
|
|
342
202
|
|
|
343
|
-
The MCP configuration files are written to each tool's own config directory — not into `~/.hmem/`:
|
|
344
|
-
|
|
345
|
-
| Tool | Global MCP config path |
|
|
346
|
-
|---|---|
|
|
347
|
-
| Claude Code | `~/.claude/.mcp.json` |
|
|
348
|
-
| OpenCode | `~/.config/opencode/opencode.json` |
|
|
349
|
-
| Cursor | `~/.cursor/mcp.json` |
|
|
350
|
-
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
|
|
351
|
-
| Cline / Roo Code | `.vscode/mcp.json` (project-only) |
|
|
352
|
-
|
|
353
203
|
---
|
|
354
204
|
|
|
355
|
-
##
|
|
205
|
+
## Cross-Device Sync (hmem-sync)
|
|
356
206
|
|
|
357
|
-
|
|
358
|
-
|----------|-------------|---------|
|
|
359
|
-
| `HMEM_PROJECT_DIR` | Root directory where `.hmem` files are stored | *(required)* |
|
|
360
|
-
| `HMEM_AGENT_ID` | Agent identifier — used as filename and directory name | `""` → `memory.hmem` |
|
|
361
|
-
| `HMEM_AGENT_ROLE` | Permission level: `worker` · `al` · `pl` · `ceo` | `worker` |
|
|
207
|
+
Sync your memories across all devices with zero-knowledge encryption.
|
|
362
208
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
## Configuration (hmem.config.json)
|
|
366
|
-
|
|
367
|
-
Place an optional `hmem.config.json` in your `HMEM_PROJECT_DIR` to tune behavior. All keys are optional — missing keys fall back to defaults.
|
|
368
|
-
|
|
369
|
-
```json
|
|
370
|
-
{
|
|
371
|
-
"maxL1Chars": 120,
|
|
372
|
-
"maxLnChars": 50000,
|
|
373
|
-
"maxDepth": 5,
|
|
374
|
-
"maxTitleChars": 50,
|
|
375
|
-
"accessCountTopN": 5,
|
|
376
|
-
"bulkReadV2": {
|
|
377
|
-
"topNewestCount": 5,
|
|
378
|
-
"topAccessCount": 3,
|
|
379
|
-
"topObsoleteCount": 3
|
|
380
|
-
},
|
|
381
|
-
"prefixes": {
|
|
382
|
-
"R": "Research"
|
|
383
|
-
}
|
|
384
|
-
}
|
|
209
|
+
```bash
|
|
210
|
+
npm install -g hmem-sync
|
|
385
211
|
```
|
|
386
212
|
|
|
387
|
-
###
|
|
213
|
+
### First device
|
|
388
214
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
| Prefix | Category | When to use |
|
|
392
|
-
|--------|----------|-------------|
|
|
393
|
-
| `P` | Project | Project experiences, summaries |
|
|
394
|
-
| `L` | Lesson | Lessons learned, best practices |
|
|
395
|
-
| `E` | Error | Bugs, errors + their fix |
|
|
396
|
-
| `D` | Decision | Architecture decisions with reasoning |
|
|
397
|
-
| `T` | Task | Task notes, work progress |
|
|
398
|
-
| `M` | Milestone | Key milestones, releases |
|
|
399
|
-
| `S` | Skill | Skills, processes, how-to guides |
|
|
400
|
-
| `N` | Navigator | Code pointers — where something lives in the codebase |
|
|
401
|
-
|
|
402
|
-
To add your own, add entries to the `"prefixes"` key in `hmem.config.json`. Custom prefixes are **merged** with the defaults — you don't need to repeat the built-in ones.
|
|
403
|
-
|
|
404
|
-
### Favorites
|
|
405
|
-
|
|
406
|
-
Any entry can be marked as a **favorite** — regardless of its prefix category. Favorites always appear with their L2 detail in bulk reads, marked with `[♥]`.
|
|
407
|
-
|
|
408
|
-
```
|
|
409
|
-
write_memory(prefix="D", content="...", favorite=true) # set at creation
|
|
410
|
-
update_memory(id="D0010", favorite=true) # set on existing entry
|
|
411
|
-
update_memory(id="D0010", favorite=false) # clear the flag
|
|
215
|
+
```bash
|
|
216
|
+
npx hmem-sync connect
|
|
412
217
|
```
|
|
413
218
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
### Pinned entries
|
|
219
|
+
Interactive wizard: creates account, generates encryption keys, pushes your data.
|
|
417
220
|
|
|
418
|
-
|
|
221
|
+
### Additional devices
|
|
419
222
|
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
update_memory(id="S0005", pinned=true) # set on existing entry
|
|
223
|
+
```bash
|
|
224
|
+
npx hmem-sync connect
|
|
423
225
|
```
|
|
424
226
|
|
|
425
|
-
|
|
426
|
-
|---|---|---|---|---|
|
|
427
|
-
| Children shown | Latest only | All titles | All titles | All with full content |
|
|
428
|
-
| `[+N more →]` hint | Yes | No | No | No |
|
|
227
|
+
Same wizard — choose "existing account", enter your credentials from the first device.
|
|
429
228
|
|
|
430
|
-
|
|
229
|
+
### Enable auto-sync
|
|
431
230
|
|
|
432
|
-
|
|
231
|
+
Add `HMEM_SYNC_PASSPHRASE` to your MCP config:
|
|
433
232
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"env": {
|
|
236
|
+
"HMEM_PROJECT_DIR": "/home/you/.hmem",
|
|
237
|
+
"HMEM_AGENT_ID": "DEVELOPER",
|
|
238
|
+
"HMEM_SYNC_PASSPHRASE": "your-passphrase"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
442
241
|
```
|
|
443
242
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
### Stale Detection and Memory Health
|
|
447
|
-
|
|
448
|
-
```
|
|
449
|
-
read_memory(stale_days=30) # entries not accessed in 30 days, sorted oldest-first
|
|
450
|
-
memory_stats() # count by prefix, stale count, favorites, most-accessed
|
|
451
|
-
memory_health() # audit: broken links, orphans, stale favorites
|
|
452
|
-
find_related(id="P0029") # FTS5 keyword similarity — find thematically related entries
|
|
453
|
-
```
|
|
243
|
+
With this set, every `read_memory` automatically pulls and every `write_memory` automatically pushes. 30-second cooldown prevents spam.
|
|
454
244
|
|
|
455
|
-
###
|
|
245
|
+
### Multi-server redundancy
|
|
456
246
|
|
|
457
|
-
|
|
247
|
+
In `hmem.config.json`, configure multiple servers:
|
|
458
248
|
|
|
459
249
|
```json
|
|
460
|
-
{
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
```
|
|
468
|
-
score = access_count / log2(age_in_days + 2)
|
|
250
|
+
{
|
|
251
|
+
"sync": [
|
|
252
|
+
{ "name": "primary", "serverUrl": "https://server1/hmem-sync", "userId": "me", "salt": "...", "token": "..." },
|
|
253
|
+
{ "name": "backup", "serverUrl": "https://server2/hmem-sync", "userId": "me", "salt": "...", "token": "..." }
|
|
254
|
+
]
|
|
255
|
+
}
|
|
469
256
|
```
|
|
470
257
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
| Mechanism | When useful |
|
|
474
|
-
|---|---|
|
|
475
|
-
| **favorite flag** | Entries you know are important from day 1 — even with zero access history |
|
|
476
|
-
| **accessCountTopN** | Entries that proved important over time — emerges from actual usage |
|
|
258
|
+
Push/pull goes to all servers. Use during migration or for redundant backup.
|
|
477
259
|
|
|
478
|
-
###
|
|
260
|
+
### Announcements
|
|
479
261
|
|
|
480
|
-
|
|
262
|
+
Broadcast urgent messages to all synced devices:
|
|
481
263
|
|
|
482
|
-
|
|
483
|
-
-
|
|
484
|
-
|
|
485
|
-
A **session cache** tracks which entries were already shown. Subsequent bulk reads suppress seen entries with Fibonacci decay `[5,3,2,1,0]`, keeping output fresh without repetition. Use `reset_memory_cache` to clear the cache.
|
|
264
|
+
```bash
|
|
265
|
+
npx hmem-sync announce --message "Server URL changing — update your config!"
|
|
266
|
+
```
|
|
486
267
|
|
|
487
|
-
|
|
268
|
+
All devices see the announcement on next sync pull.
|
|
488
269
|
|
|
489
|
-
|
|
270
|
+
---
|
|
490
271
|
|
|
491
|
-
|
|
272
|
+
## Auto-Logging (O-prefix)
|
|
492
273
|
|
|
493
|
-
|
|
274
|
+
With Claude Code's Stop hook, every conversation exchange (your message + agent response) is automatically recorded in O-prefix entries. Zero token cost — runs in the background.
|
|
494
275
|
|
|
495
|
-
|
|
276
|
+
### Setup the hook
|
|
496
277
|
|
|
497
|
-
|
|
278
|
+
Add to `~/.claude/settings.json`:
|
|
498
279
|
|
|
499
280
|
```json
|
|
500
|
-
{
|
|
281
|
+
{
|
|
282
|
+
"hooks": {
|
|
283
|
+
"Stop": [
|
|
284
|
+
{
|
|
285
|
+
"hooks": [
|
|
286
|
+
{
|
|
287
|
+
"type": "command",
|
|
288
|
+
"command": "HMEM_PROJECT_DIR=/home/you/.hmem HMEM_AGENT_ID=DEVELOPER node /path/to/hmem-mcp/dist/cli.js log-exchange",
|
|
289
|
+
"timeout": 10
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
}
|
|
295
|
+
}
|
|
501
296
|
```
|
|
502
297
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
**Option B — explicit per-level array**: set each level individually. If fewer entries than `maxDepth`, the last value is repeated.
|
|
298
|
+
O-entries are hidden from bulk reads (no noise) but searchable and linked to your active project.
|
|
506
299
|
|
|
507
|
-
|
|
508
|
-
{ "maxCharsPerLevel": [120, 2500, 10000, 25000, 50000] }
|
|
509
|
-
```
|
|
300
|
+
---
|
|
510
301
|
|
|
511
|
-
|
|
302
|
+
## Configuration
|
|
512
303
|
|
|
513
|
-
|
|
304
|
+
`hmem.config.json` in your `HMEM_PROJECT_DIR`:
|
|
514
305
|
|
|
515
306
|
```json
|
|
516
|
-
|
|
517
|
-
"
|
|
518
|
-
|
|
519
|
-
|
|
307
|
+
{
|
|
308
|
+
"memory": {
|
|
309
|
+
"maxCharsPerLevel": [200, 2500, 10000, 25000, 50000],
|
|
310
|
+
"maxDepth": 5,
|
|
311
|
+
"maxTitleChars": 50,
|
|
312
|
+
"prefixes": { "X": "Custom" }
|
|
313
|
+
},
|
|
314
|
+
"sync": {
|
|
315
|
+
"serverUrl": "https://your-server/hmem-sync",
|
|
316
|
+
"userId": "yourname",
|
|
317
|
+
"salt": "...",
|
|
318
|
+
"token": "..."
|
|
319
|
+
}
|
|
520
320
|
}
|
|
521
321
|
```
|
|
522
322
|
|
|
523
|
-
|
|
323
|
+
All keys are optional. Missing keys use defaults.
|
|
524
324
|
|
|
525
325
|
---
|
|
526
326
|
|
|
527
|
-
##
|
|
528
|
-
|
|
529
|
-
A terminal-based interactive viewer for browsing `.hmem` memory files. Built with [Textual](https://textual.textualize.io/).
|
|
327
|
+
## Updating
|
|
530
328
|
|
|
531
329
|
```bash
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
python3 hmem-reader.py ~/path/to/file.hmem # open any .hmem file directly
|
|
330
|
+
# Always global — NOT inside a project directory
|
|
331
|
+
npm update -g hmem-mcp
|
|
332
|
+
npm update -g hmem-sync
|
|
536
333
|
```
|
|
537
334
|
|
|
538
|
-
|
|
539
|
-
| Key | Action |
|
|
540
|
-
|-----|--------|
|
|
541
|
-
| `r` | Toggle V2 bulk-read view (what agents see on `read_memory()`) |
|
|
542
|
-
| `e` / `c` | Expand / collapse all nodes |
|
|
543
|
-
| `q` | Quit |
|
|
544
|
-
| `Escape` | Back to agent list |
|
|
545
|
-
|
|
546
|
-
The V2 view mirrors the MCP server's bulk-read algorithm — including time-weighted access scoring, per-prefix selection, active-prefix filtering, and all markers (`[♥]`, `[!]`, `[*]`, `[s]`, `[-]`) — so you can see exactly what an agent sees at session start.
|
|
547
|
-
|
|
548
|
-
---
|
|
549
|
-
|
|
550
|
-
## Origin
|
|
551
|
-
|
|
552
|
-
hmem was developed out of necessity: working on a large AI project across multiple machines meant every new Claude Code session started blind. Agents redid work, lost decisions, and contradicted each other.
|
|
553
|
-
|
|
554
|
-
The solution was a memory protocol that works the way humans remember — broad strokes first, details on demand.
|
|
335
|
+
Skills are automatically updated via postinstall hook. No manual copy needed.
|
|
555
336
|
|
|
556
337
|
---
|
|
557
338
|
|