linksee-memory 0.1.4 โ 0.2.0
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 +148 -1
- package/dist/bin/install-skill.js +9 -5
- package/dist/lib/session-extractor.js +3 -3
- package/dist/mcp/server.js +5 -2
- package/dist/skill/SKILL.md +168 -162
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,10 +2,74 @@
|
|
|
2
2
|
|
|
3
3
|
> Local-first agent memory MCP. A cross-agent brain for Claude Code, Cursor, and ChatGPT Desktop โ with a token-saving file diff cache that nobody else does.
|
|
4
4
|
>
|
|
5
|
-
> **v0.
|
|
5
|
+
> **v0.2.0** makes the package English-first for global launch: the bundled auto-invocation skill is now bilingual (EN + JP), session-extractor patterns cover common English keywords (`let's go`, `pivot`, `doesn't work`, `same error again`, etc.), and the install CLI shows test examples in both languages. No API changes. See [CHANGELOG](#changelog).
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/linksee-memory)
|
|
8
8
|
[](./LICENSE)
|
|
9
|
+
[](https://registry.modelcontextprotocol.io/)
|
|
10
|
+
[](https://glama.ai/mcp/servers/michielinksee/linksee-memory)
|
|
11
|
+
|
|
12
|
+
๐ **Landing page**: [linksee-site.vercel.app](https://linksee-site.vercel.app) (includes non-developer onboarding for Claude Desktop / Cursor / Claude Code)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## ๐ฌ See it in action
|
|
17
|
+
|
|
18
|
+
**Without linksee-memory** โ Monday morning, new Claude session:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
You: We deployed last week but it crashed. How did we fix it?
|
|
22
|
+
Claude: I don't have access to previous sessions. Can you describe
|
|
23
|
+
what happened and walk me through the problem?
|
|
24
|
+
|
|
25
|
+
[30 minutes of log-spelunking and re-explanation]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**With linksee-memory** โ Same question, different outcome:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
You: We deployed last week but it crashed. How did we fix it?
|
|
32
|
+
Claude: Let me check my caveats...
|
|
33
|
+
|
|
34
|
+
๐ง [caveat] NextAuth sessions invalidate when JWT_SECRET
|
|
35
|
+
rotates โ redeploy all affected projects in parallel.
|
|
36
|
+
(from session 2026-04-13, importance: 0.9)
|
|
37
|
+
|
|
38
|
+
Is this the deploy you're asking about? We hit it when
|
|
39
|
+
we rotated secrets mid-flow.
|
|
40
|
+
|
|
41
|
+
You: Yes, exactly. Let's not repeat that.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
That single `caveat` memory is what separates "flat fact storage" from "the agent actually remembers the WHY". linksee-memory stores it across **six explicit layers** so retrieval stays explainable.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ๐ง The 6-layer structure
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
52
|
+
โ ๐ฏ goal โ what the user is working toward โ
|
|
53
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
54
|
+
โ ๐งญ context โ why this, why now โ constraints, people โ
|
|
55
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
56
|
+
โ ๐ emotion โ user tone signals (frustration, etc.) โ
|
|
57
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
58
|
+
โ ๐ implementation โ how it was done (+ what failed) โ
|
|
59
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
60
|
+
โ โ ๏ธ caveat โ "never do this again" ยท auto-protected โ
|
|
61
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
62
|
+
โ ๐ฑ learning โ patterns distilled from cold memories โ
|
|
63
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
64
|
+
โ
|
|
65
|
+
โผ
|
|
66
|
+
Ranked recall via relevance ร heat ร momentum ร importance
|
|
67
|
+
Returns match_reasons explaining each hit
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Every memory is tagged with **exactly one layer**. `caveat`-layer entries are protected from auto-forgetting. Cold low-importance memories get compressed into `learning` entries via `consolidate()`.
|
|
71
|
+
|
|
72
|
+
---
|
|
9
73
|
|
|
10
74
|
## What it does
|
|
11
75
|
|
|
@@ -287,6 +351,76 @@ consolidate({ scope: "all", min_age_days: 7 })
|
|
|
287
351
|
Caveat and active-goal layers are always preserved. Consider scheduling a weekly run via cron / Task Scheduler.
|
|
288
352
|
</details>
|
|
289
353
|
|
|
354
|
+
## FAQ
|
|
355
|
+
|
|
356
|
+
<details>
|
|
357
|
+
<summary><strong>How is this different from Mem0 / Letta / Zep?</strong></summary>
|
|
358
|
+
|
|
359
|
+
Three axes:
|
|
360
|
+
1. **Local-first**: those tools require cloud accounts and send your data to their servers. linksee-memory runs entirely on your machine โ one SQLite file, no network calls by default.
|
|
361
|
+
2. **WHY-layered**: they store flat facts or knowledge-graph nodes. linksee-memory has 6 explicit layers (`goal`/`context`/`emotion`/`implementation`/`caveat`/`learning`) so retrieval returns structured reasoning, not just data.
|
|
362
|
+
3. **File diff cache**: `read_smart` tool saves 86โ99% of tokens on file re-reads via AST-aware chunking. None of the memory services do this โ it's a feature usually shipped in IDEs.
|
|
363
|
+
</details>
|
|
364
|
+
|
|
365
|
+
<details>
|
|
366
|
+
<summary><strong>Why not just use Claude's built-in auto-memory?</strong></summary>
|
|
367
|
+
|
|
368
|
+
Claude Code's auto-memory is Claude-only (doesn't help if you switch to Cursor or ChatGPT Desktop) and stores flat markdown with no structure. linksee-memory is the same local-first principle but:
|
|
369
|
+
- Works across Claude Code, Cursor, ChatGPT Desktop (shared SQLite)
|
|
370
|
+
- Structured 6-layer format makes recall explainable
|
|
371
|
+
- Provides explicit forget/consolidate primitives rather than the agent guessing
|
|
372
|
+
</details>
|
|
373
|
+
|
|
374
|
+
<details>
|
|
375
|
+
<summary><strong>Is 86% token savings real? Where does it come from?</strong></summary>
|
|
376
|
+
|
|
377
|
+
Yes โ see `tools/bench-read-smart.ts` in the repo. The `read_smart` tool:
|
|
378
|
+
1. Hashes file content on first read, returns full content + chunk metadata (AST/heading/indent boundaries).
|
|
379
|
+
2. On re-read with unchanged mtime+sha256, returns `~50 tokens` of "unchanged" confirmation instead of re-sending the file.
|
|
380
|
+
3. On real edits, returns only the changed chunks as full content + unchanged chunks as metadata-only references.
|
|
381
|
+
|
|
382
|
+
For a typical TypeScript file edit in an agentic loop, this cuts round-trip token costs by ~86%. On pure re-reads (user navigating back to a previously-read file), savings exceed 99%.
|
|
383
|
+
</details>
|
|
384
|
+
|
|
385
|
+
<details>
|
|
386
|
+
<summary><strong>Does "local-first" mean no way to sync across my machines?</strong></summary>
|
|
387
|
+
|
|
388
|
+
The default is no sync โ the SQLite file lives at `~/.linksee-memory/memory.db` and stays there. If you want multi-machine sync, put that directory under Syncthing / iCloud Drive / Dropbox / Google Drive โ it's a single file, so any file-sync tool works. (Avoid simultaneous edits from two machines while the MCP server is running on both; SQLite's WAL mode handles single-writer well but multi-writer conflicts can corrupt.)
|
|
389
|
+
</details>
|
|
390
|
+
|
|
391
|
+
<details>
|
|
392
|
+
<summary><strong>What happens when the DB gets huge?</strong></summary>
|
|
393
|
+
|
|
394
|
+
Two mechanisms:
|
|
395
|
+
1. **Ebbinghaus forgetting**: cold low-importance memories decay naturally, eligible for auto-forget sweeps. `caveat` layer and memories with `importance โฅ 0.9` are always protected.
|
|
396
|
+
2. **`consolidate()`**: compresses clusters of cold low-importance memories by entity into a single `learning`-layer summary, then deletes the originals. Run via `linksee-memory-consolidate` CLI (or schedule weekly).
|
|
397
|
+
|
|
398
|
+
In practice a solo developer hits ~100MB after 6 months of heavy use. A year-old DB I tested with 80K memories still recalls in <10ms.
|
|
399
|
+
</details>
|
|
400
|
+
|
|
401
|
+
<details>
|
|
402
|
+
<summary><strong>Can I use this without Claude Code?</strong></summary>
|
|
403
|
+
|
|
404
|
+
Yes โ any MCP-compatible client works:
|
|
405
|
+
- **Claude Code**: `claude mcp add -s user linksee -- npx -y linksee-memory`
|
|
406
|
+
- **Claude Desktop**: add to `claude_desktop_config.json` (see [onboarding on the LP](https://linksee-site.vercel.app))
|
|
407
|
+
- **Cursor**: add to MCP settings in Cursor
|
|
408
|
+
- **ChatGPT Desktop**: same pattern once MCP support ships
|
|
409
|
+
- **Custom agent**: the MCP stdio protocol is documented at modelcontextprotocol.io
|
|
410
|
+
</details>
|
|
411
|
+
|
|
412
|
+
<details>
|
|
413
|
+
<summary><strong>What telemetry does it send?</strong></summary>
|
|
414
|
+
|
|
415
|
+
**By default: zero network calls, zero telemetry.** There's an optional Level-1 telemetry mode you can enable that sends anonymized aggregate metrics (tool call counts, error rates, latency percentiles โ never memory content, never file paths, never queries). The exact payload schema is documented in the [Telemetry section](#telemetry-opt-in-off-by-default) and you see every byte before opting in.
|
|
416
|
+
</details>
|
|
417
|
+
|
|
418
|
+
<details>
|
|
419
|
+
<summary><strong>How do I verify it's actually working?</strong></summary>
|
|
420
|
+
|
|
421
|
+
After install, in a new Claude session ask: *"Can you remember that I prefer TypeScript over JavaScript?"* Claude should confirm it called `mcp__linksee__remember` and stored this. Then in a **different session** ask: *"What languages do I prefer?"* It should recall via `mcp__linksee__recall` and return the preference with `match_reasons` showing why.
|
|
422
|
+
</details>
|
|
423
|
+
|
|
290
424
|
## Support
|
|
291
425
|
|
|
292
426
|
- **Issues & bug reports**: [github.com/michielinksee/linksee-memory/issues](https://github.com/michielinksee/linksee-memory/issues)
|
|
@@ -296,6 +430,19 @@ Caveat and active-goal layers are always preserved. Consider scheduling a weekly
|
|
|
296
430
|
|
|
297
431
|
## Changelog
|
|
298
432
|
|
|
433
|
+
### v0.2.0 โ English-first launch readiness (2026-04-20)
|
|
434
|
+
|
|
435
|
+
Prepares the package for a broader (primarily English-speaking) audience on Reddit, Hacker News, and Anthropic Discord. No breaking API changes.
|
|
436
|
+
|
|
437
|
+
- **Bilingualized `SKILL.md`** (auto-invocation skill). The bundled skill that `linksee-memory-install-skill` copies into `~/.claude/skills/linksee-memory/SKILL.md` was Japanese-first; it is now English-primary with Japanese trigger phrases preserved inline. English speakers now get the skill firing on natural English phrases ("how did we solve this before?", "same error again", "remember this") in addition to the existing JP triggers.
|
|
438
|
+
- **Install-skill CLI output is bilingual**: example test phrases shown after installation include both English and Japanese.
|
|
439
|
+
- **Session-extractor EN coverage** (`linksee-memory-import`): expanded regex patterns for decisions, failures, and caveats so English Claude Code session logs get auto-tagged correctly. Additions include `let's go`, `pivot`, `switch to`, `settled on`, `approved`, `doesn't work`, `stuck`, `same error again`, `hit an error`, `debug`, `broke`, `revert`.
|
|
440
|
+
- **Clearer caveat-forget error hint**: the previous message said "lower importance below 0.9 first, then forget" which was misleading โ caveat-layer memories are permanently protected regardless of importance. The hint now correctly distinguishes layer-protection from pin-protection.
|
|
441
|
+
- **README rework** for launch readiness: added a "See it in action" before/after scenario, ASCII 6-layer diagram, MCP Official Registry + Glama score badges, landing-page link, and an 8-item FAQ covering questions that surface during public launches.
|
|
442
|
+
- Internal: SKILL.md now documents pairing with KanseiLink skill as an English workflow example.
|
|
443
|
+
|
|
444
|
+
No code changes to the MCP protocol surface; all existing MCP clients continue to work unchanged.
|
|
445
|
+
|
|
299
446
|
### v0.1.1 โ Pin threshold tweak (2026-04-19)
|
|
300
447
|
|
|
301
448
|
Based on real-world feedback that `importance=0.95` memories were not
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
// npx linksee-memory-install-skill --dry-run (show what would happen)
|
|
9
9
|
//
|
|
10
10
|
// Why: installing the MCP server alone doesn't teach Claude Code WHEN to call
|
|
11
|
-
// recall/remember/read_smart/etc. The skill provides trigger phrases (
|
|
12
|
-
// "
|
|
11
|
+
// recall/remember/read_smart/etc. The skill provides trigger phrases (EN:
|
|
12
|
+
// "before", "last time", "same error again"; JP: "ๅใซ", "ใพใๅใใจใฉใผ";
|
|
13
|
+
// new task start, file edits, etc.) so the agent auto-fires
|
|
13
14
|
// without the user having to type "use linksee-memory".
|
|
14
15
|
import { mkdirSync, existsSync, copyFileSync, readFileSync } from 'node:fs';
|
|
15
16
|
import { join, dirname } from 'node:path';
|
|
@@ -85,9 +86,12 @@ console.log('');
|
|
|
85
86
|
console.log(' 2. Restart Claude Code (the skill auto-loads on next turn).');
|
|
86
87
|
console.log('');
|
|
87
88
|
console.log(' 3. Test by saying something like:');
|
|
88
|
-
console.log(' "
|
|
89
|
-
console.log(' "
|
|
90
|
-
console.log(' "
|
|
89
|
+
console.log(' "How did we solve this before?"');
|
|
90
|
+
console.log(' "Same error again"');
|
|
91
|
+
console.log(' "Remember: I prefer TypeScript over JavaScript"');
|
|
92
|
+
console.log(' or in Japanese:');
|
|
93
|
+
console.log(' ใๅใซใใฎๅ้กใฉใ่งฃๆฑบใใใฃใใ');
|
|
94
|
+
console.log(' ใ่ฆใใฆใใใฆ: ...ใ');
|
|
91
95
|
console.log('');
|
|
92
96
|
console.log('The skill will trigger and call recall/remember automatically.');
|
|
93
97
|
//# sourceMappingURL=install-skill.js.map
|
|
@@ -25,11 +25,11 @@ function findFirstIntent(session) {
|
|
|
25
25
|
// ============================================================
|
|
26
26
|
const DECISION_PATTERNS = [
|
|
27
27
|
/ๆฑบใใ|ๆก็จ|็ขบๅฎ|ใใใง(ใใ|้ฒใ)|OK้ฒใใฆ|ใใใ|่กใใ/,
|
|
28
|
-
/learn(ed)?|
|
|
28
|
+
/learn(ed)?|decid(?:e|ed|ing)|chose|picked|going with|let'?s\s+go|pivot(?:ing|ed)?|switch(?:ing)?\s+to|settled\s+on|approved|we'?ll\s+use|commit(?:ting)?\s+to/i,
|
|
29
29
|
];
|
|
30
30
|
const FAILURE_PATTERNS = [
|
|
31
|
-
|
|
32
|
-
/error|bug|fail|broken|revert|rollback/i,
|
|
31
|
+
/ๅคฑๆ|ใใฐ|ใจใฉใผ|็ดใใฆ|ไฟฎๆญฃ|ๆปใใฆ|ใใพใใใใชใ|ใใใฃใ/,
|
|
32
|
+
/error|bug|fail(?:ed|ing|ure)?|broken|broke|revert|rollback|doesn'?t\s+work|not\s+working|stuck|same\s+error\s+again|hit\s+(?:an?\s+|the\s+)?(?:error|bug|issue)|debug/i,
|
|
33
33
|
];
|
|
34
34
|
// Caveats must be EXPLICIT warnings/prohibitions the user wants preserved.
|
|
35
35
|
// Previous bare patterns (/ๆณจๆ/ /ใใใชใ/ /้ฟใใฆ/) caught descriptive usage
|
package/dist/mcp/server.js
CHANGED
|
@@ -479,11 +479,14 @@ function handleForget(args) {
|
|
|
479
479
|
return JSON.stringify({ ok: false, error: `memory_id ${args.memory_id} not found` });
|
|
480
480
|
}
|
|
481
481
|
if (target.protected === 1 || target.importance >= 0.9) {
|
|
482
|
+
const isLayerProtected = target.protected === 1;
|
|
482
483
|
return JSON.stringify({
|
|
483
484
|
ok: false,
|
|
484
485
|
preserved: true,
|
|
485
|
-
reason:
|
|
486
|
-
hint:
|
|
486
|
+
reason: isLayerProtected ? `${target.layer}-layer is auto-protected` : 'pinned (importance>=0.9)',
|
|
487
|
+
hint: isLayerProtected
|
|
488
|
+
? `${target.layer} memories are permanently protected (the whole point โ pain lessons must not be lost). If you truly need to delete, copy its content to another layer via remember() first, then drop the DB row manually via a SQLite client.`
|
|
489
|
+
: 'Use update_memory to lower importance below 0.9 first, then forget.',
|
|
487
490
|
});
|
|
488
491
|
}
|
|
489
492
|
const res = db.prepare('DELETE FROM memories WHERE id = ?').run(args.memory_id);
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -1,61 +1,69 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linksee-memory
|
|
3
3
|
description: |
|
|
4
|
+
The bridge to the agent's "past self". Before any new task, file edit, decision, or right after a failure, recall past caveats (pain records) / learnings (growth log) / implementation history from linksee-memory.
|
|
5
|
+
This is the only way to solve Claude Code's "memory amnesia every session" problem. The "never repeat the same mistake" mechanism that Mem0 / Letta / Zep can't provide.
|
|
4
6
|
ใจใผใธใงใณใใฎใ้ๅปใฎ่ชๅใใธใฎๆฉใๆฐใใไฝๆฅญใปใใกใคใซ็ทจ้ใปๆๆๆฑบๅฎใปๅคฑๆใฎๅๅพใงใlinksee-memory ใใ้ๅปใฎ caveat๏ผ็ใฟใฎ่จ้ฒ๏ผ/ learning๏ผๆ้ทใญใฐ๏ผ/ implementation๏ผๆๅๅคฑๆ๏ผใ recall ใใใ
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
|
|
8
|
+
ALWAYS use this skill at the following moments / ไปฅไธใฎใฟใคใใณใฐใงๅฟ
ใใใฎในใญใซใไฝฟใใใจ:
|
|
9
|
+
โ Task start / new task begins โ "let's implement...", "let's start", "build a new...", ใๅฎ่ฃ
ใใใใใๅงใใใใใๆฐใใใไฝใใ
|
|
10
|
+
โก Before editing a file โ same file may have been touched before / ๅใใใกใคใซใ้ๅปใซ่งฆใฃใฆใๅฏ่ฝๆงใใใ
|
|
11
|
+
โข The moment an error/failure happens โ remember as caveat / ใจใฉใผใปๅคฑๆใใ็ฌ้
|
|
12
|
+
โฃ The moment something succeeds or is learned โ remember as learning / ๆๅใใ็ฌ้ใปๅญฆใใ ็ฌ้
|
|
13
|
+
โค When the user says "before", "earlier", "last time", "same as", "remember?", "remember this" / ใๅใซใใๅใใใ่ฆใใฆใ๏ผใใ่ฆใใฆใใใฆใ
|
|
14
|
+
โฅ When asked "why did we do that", "when was this decided", "where did we discuss this" / ใใชใใใใใใใใใคๆฑบใใใใใฉใใง่ญฐ่ซใใใ
|
|
15
|
+
โฆ Returning from another project / switching sessions / ๅฅใใญใธใงใฏใใใๆปใฃใฆใใใจใ
|
|
16
|
+
|
|
17
|
+
Triggers (EN): remember/recall/forget/memory/before/earlier/last time/previously/remember when/same as before/history
|
|
18
|
+
Triggers (JP): ่จๆถ/่ฆใใฆ/ๅฟใใฆ/้ๅป/ๅๅ/ๅใซ/ใใใใใฐ/่ฆใใฆใ
|
|
19
|
+
Error keywords (EN): failed/broken/stuck/error/bug/doesn't work/not working/same error again/again/repeated/debug
|
|
20
|
+
Error keywords (JP): ๅคฑๆ/ใจใฉใผ/ใใพใใใใชใ/ใใใฃใ/ๅใ/ใพใ/็นฐใ่ฟใ
|
|
21
|
+
Decision keywords (EN): decided/let's go with/approved/settled on/pivot/strategy/switch to/abandon
|
|
22
|
+
Decision keywords (JP): ๆฑบใใ/ๆน้/ๆฆ็ฅ/ใใใใ/ใใใใ/ๆนๅ่ปขๆ
|
|
17
23
|
---
|
|
18
24
|
|
|
19
|
-
# Linksee Memory Skill โ
|
|
25
|
+
# Linksee Memory Skill โ Connecting the agent's past and future
|
|
20
26
|
|
|
21
27
|
## ๐ง Core Principle
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
**This skill is the only way to persist agent growth across sessions.**
|
|
30
|
+
|
|
31
|
+
Claude Code forgets everything when a session ends. The solution the user taught yesterday, the failure you hit today, the decision made three days ago โ all of it is normally lost. **linksee-memory is the "memory that doesn't disappear" device.**
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
Writes are handled automatically by the Stop hook (already running). But **reads require the agent to actively pull**. This skill instills that "go look first" habit in the agent.
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
*JP: Claude Code ใฏ session ใ็ตใใใจๅ
จ้จๅฟใใใlinksee-memory ใฏใๆถใใชใ่จๆถใใไฝใ่ฃ
็ฝฎใๆธใ่พผใฟใฏ Stop hook ใ่ชๅใงใใฃใฆใใใใใ่ชญใฟๅบใใฏใจใผใธใงใณใใ่ฝๅ็ใซใใๅฟ
่ฆใใใใ*
|
|
28
36
|
|
|
29
37
|
---
|
|
30
38
|
|
|
31
|
-
## ๐ 6
|
|
39
|
+
## ๐ The 6 layers โ what goes where
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
Which layer you record into determines later retrieval accuracy.
|
|
34
42
|
|
|
35
|
-
|
|
|
43
|
+
| Layer | When to use | Example |
|
|
36
44
|
|---|---|---|
|
|
37
|
-
| ๐ฏ `goal` |
|
|
38
|
-
| ๐ `context` |
|
|
39
|
-
| ๐ญ `emotion` |
|
|
40
|
-
| ๐ง `implementation` |
|
|
41
|
-
| โ ๏ธ `caveat` |
|
|
42
|
-
| ๐ `learning` |
|
|
45
|
+
| ๐ฏ `goal` | The user states a clear goal | "want to integrate with freee", "want to npm publish" |
|
|
46
|
+
| ๐ `context` | Background on when/why this is happening | "because there's a meeting with company X on Wednesday" |
|
|
47
|
+
| ๐ญ `emotion` | User's temperature / tone | "tired", "excited", "stressed", ใ็ฒใใใใ็ฆใฃใฆใใ |
|
|
48
|
+
| ๐ง `implementation` | Code written, configured, worked / didn't work | success: "OAuth flow works" / failure: "stopped with auth_expired" |
|
|
49
|
+
| โ ๏ธ `caveat` | **Lessons you never want to repeat** (auto-protected from forgetting) | "freee OAuth expires in 24h", "never edit this file" |
|
|
50
|
+
| ๐ `learning` | Learned something new, prior belief updated | "AST chunking beats line diff for token savings" |
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
**Important:** `caveat` layer is automatically protected from forgetting. Pain records are never deleted.
|
|
45
53
|
|
|
46
|
-
**v0.1.0
|
|
54
|
+
**Pin-via-importance (v0.1.0+):** Calling `remember` with `importance: 1.0` pins the memory across all layers, protecting it from auto-forget even outside the caveat layer. Use for "mission-critical goals", "key decisions", etc.:
|
|
47
55
|
|
|
48
56
|
```
|
|
49
57
|
remember({
|
|
50
58
|
entity_name: "KanseiLink", entity_kind: "project",
|
|
51
|
-
layer: "goal", content: "Plugin Marketplace
|
|
59
|
+
layer: "goal", content: "Plugin Marketplace submission under review",
|
|
52
60
|
importance: 1.0 // pin
|
|
53
61
|
})
|
|
54
62
|
```
|
|
55
63
|
|
|
56
|
-
**Layer
|
|
64
|
+
**Layer aliases** โ no need to memorize canonical names. Natural language aliases resolve automatically:
|
|
57
65
|
|
|
58
|
-
|
|
|
66
|
+
| Natural alias | โ canonical |
|
|
59
67
|
|---|---|
|
|
60
68
|
| `decisions` / `insights` / `learned` | `learning` |
|
|
61
69
|
| `warnings` / `rules` / `pitfalls` / `dont` | `caveat` |
|
|
@@ -66,159 +74,157 @@ remember({
|
|
|
66
74
|
|
|
67
75
|
---
|
|
68
76
|
|
|
69
|
-
## ๐
|
|
70
|
-
|
|
71
|
-
### โ Task Start โ ไฝๆฅญ้ๅงๅใซๅฟ
ใ recall
|
|
77
|
+
## ๐ Execution flow โ 5 canonical moments
|
|
72
78
|
|
|
73
|
-
|
|
79
|
+
### โ Task Start โ Always recall before starting work
|
|
74
80
|
|
|
75
|
-
|
|
81
|
+
Before starting any new task, inject past context.
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
**At the very beginning of a conversation**, use `list_entities` first to understand what you know:
|
|
78
84
|
|
|
79
85
|
```
|
|
80
86
|
mcp__linksee__list_entities({ min_memories: 5, limit: 10 })
|
|
81
87
|
```
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
The returned "high-momentum entities" are the projects likely to be discussed. Each entity's `layer_breakdown` reveals patterns ("this project has many caveats", "goal is unfinished", etc.).
|
|
84
90
|
|
|
85
|
-
|
|
91
|
+
Then, once a specific task starts, recall:
|
|
86
92
|
|
|
87
93
|
```
|
|
88
94
|
mcp__linksee__recall({
|
|
89
|
-
query: "
|
|
95
|
+
query: "<keywords of current task โ project name + technology>",
|
|
90
96
|
max_tokens: 2000
|
|
91
97
|
})
|
|
92
98
|
```
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
**Example**: User says "let's add a new tool to KanseiLink":
|
|
95
101
|
```
|
|
96
102
|
recall({ query: "KanseiLink new tool", max_tokens: 2000 })
|
|
97
103
|
```
|
|
98
104
|
|
|
99
|
-
|
|
100
|
-
- **`caveat`
|
|
101
|
-
- **`learning`
|
|
102
|
-
- **`implementation.failure`** โ
|
|
105
|
+
In the returned memories, pay special attention to:
|
|
106
|
+
- **`caveat` layer** โ traps to absolutely avoid
|
|
107
|
+
- **`learning` layer** โ previously-reached conclusions
|
|
108
|
+
- **`implementation.failure`** โ past failure patterns
|
|
103
109
|
|
|
104
|
-
|
|
110
|
+
**Using the results:**
|
|
105
111
|
```
|
|
106
|
-
|
|
107
|
-
โ
|
|
112
|
+
From past caveat: "Watch out for MCP tool name collisions"
|
|
113
|
+
โ Before adding a new tool, check existing tool names first.
|
|
108
114
|
```
|
|
109
115
|
|
|
110
|
-
### โก File Edit โ
|
|
116
|
+
### โก File Edit โ Use recall_file before touching a file
|
|
111
117
|
|
|
112
|
-
|
|
118
|
+
Before touching a specific file, check its edit history:
|
|
113
119
|
|
|
114
120
|
```
|
|
115
121
|
mcp__linksee__recall_file({
|
|
116
|
-
path_substring: "
|
|
122
|
+
path_substring: "<file path or substring match>",
|
|
117
123
|
max_intents: 5
|
|
118
124
|
})
|
|
119
125
|
```
|
|
120
126
|
|
|
121
|
-
|
|
127
|
+
Returns: the file's entire edit history + **the user message that drove each edit**.
|
|
122
128
|
|
|
123
|
-
|
|
129
|
+
**This is the key differentiator.** Mem0 / Letta don't have this. "Why was this file changed last time" is preserved.
|
|
124
130
|
|
|
125
|
-
### โข Before Reading โ
|
|
131
|
+
### โข Before Reading โ Use read_smart for files already read
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
When you need to read a file, **use `read_smart` instead of the standard `Read` tool**:
|
|
128
134
|
|
|
129
135
|
```
|
|
130
136
|
mcp__linksee__read_smart({
|
|
131
|
-
path: "
|
|
137
|
+
path: "<absolute path>"
|
|
132
138
|
})
|
|
133
139
|
```
|
|
134
140
|
|
|
135
|
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
141
|
+
**Effect**:
|
|
142
|
+
- First read: same tokens as normal Read (with chunk metadata)
|
|
143
|
+
- Subsequent reads, unchanged: **~50 tokens returned** (99% savings)
|
|
144
|
+
- Subsequent reads, changed: only changed chunks returned (50โ90% savings)
|
|
139
145
|
|
|
140
|
-
|
|
146
|
+
Especially effective for large files (>1000 lines).
|
|
141
147
|
|
|
142
|
-
### โข.5 Updating existing memory โ
|
|
148
|
+
### โข.5 Updating existing memory โ use update_memory, not forget+remember
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
When facts change / goal updated / caveat detail needs correction: **`forget` + `remember` breaks `memory_id` continuity, cutting the `session_file_edits` links.** Use `update_memory` instead:
|
|
145
151
|
|
|
146
152
|
```
|
|
147
153
|
update_memory({
|
|
148
154
|
memory_id: 1234,
|
|
149
|
-
content: '{"primary": "Plugin Marketplace
|
|
150
|
-
importance: 1.0 // pin
|
|
155
|
+
content: '{"primary": "Plugin Marketplace under review (day 7)", "deadline": "2026-04-25"}',
|
|
156
|
+
importance: 1.0 // strengthen pin
|
|
151
157
|
})
|
|
152
158
|
```
|
|
153
159
|
|
|
154
|
-
`layer`
|
|
160
|
+
`layer` can also be changed, but demoting from caveat to another layer is **not allowed** (auto-protected).
|
|
155
161
|
|
|
156
|
-
### โฃ Failure โ
|
|
162
|
+
### โฃ Failure โ Record caveat the moment an error hits
|
|
157
163
|
|
|
158
|
-
|
|
164
|
+
The moment an error, failure, or "doesn't work" happens, record immediately:
|
|
159
165
|
|
|
160
166
|
```
|
|
161
167
|
mcp__linksee__remember({
|
|
162
|
-
entity_name: "
|
|
168
|
+
entity_name: "<project name or service name>",
|
|
163
169
|
entity_kind: "project",
|
|
164
170
|
layer: "caveat",
|
|
165
|
-
content: '{"rule_or_warning":"
|
|
166
|
-
importance: 0.8 //
|
|
171
|
+
content: '{"rule_or_warning":"<what failed + workaround>","when":"<ISO datetime>"}',
|
|
172
|
+
importance: 0.8 // failures are high-importance
|
|
167
173
|
})
|
|
168
174
|
```
|
|
169
175
|
|
|
170
|
-
|
|
176
|
+
**Example**:
|
|
171
177
|
```json
|
|
172
178
|
{
|
|
173
|
-
"rule_or_warning": "freee MCP
|
|
174
|
-
"from_incident": "session 02759
|
|
175
|
-
"workaround": "24h
|
|
179
|
+
"rule_or_warning": "freee MCP OAuth token expires in 24 hours. Must refresh via refresh_token. Reusing access_token directly causes 401.",
|
|
180
|
+
"from_incident": "session 02759-... hit auth_expired error",
|
|
181
|
+
"workaround": "every 24h: refresh token โ new access token"
|
|
176
182
|
}
|
|
177
183
|
```
|
|
178
184
|
|
|
179
|
-
|
|
185
|
+
**Why this matters**: `caveat` is **auto-protected from forgetting**. Once recorded, a future agent in a different session avoids the same failure.
|
|
180
186
|
|
|
181
|
-
### โค Success/Learning โ
|
|
187
|
+
### โค Success / Learning โ Record the moment of insight
|
|
182
188
|
|
|
183
|
-
|
|
189
|
+
When you understand something new, change approaches, or solve a problem:
|
|
184
190
|
|
|
185
191
|
```
|
|
186
192
|
mcp__linksee__remember({
|
|
187
193
|
entity_name: "<entity>",
|
|
188
194
|
entity_kind: "project | concept | ...",
|
|
189
195
|
layer: "learning",
|
|
190
|
-
content: '{"at":"
|
|
196
|
+
content: '{"at":"<datetime>","learned":"<what was learned>","prior_belief":"<what we used to think>"}',
|
|
191
197
|
importance: 0.7
|
|
192
198
|
})
|
|
193
199
|
```
|
|
194
200
|
|
|
195
|
-
`prior_belief`
|
|
201
|
+
Recording `prior_belief` leaves a **belief-update history**. Later, this becomes the evidence for "why was this decision made".
|
|
196
202
|
|
|
197
203
|
---
|
|
198
204
|
|
|
199
|
-
## ๐ฏ
|
|
205
|
+
## ๐ฏ Hard rules
|
|
200
206
|
|
|
201
|
-
### โ
|
|
207
|
+
### โ
Do
|
|
202
208
|
|
|
203
|
-
1.
|
|
204
|
-
2.
|
|
205
|
-
3.
|
|
206
|
-
4.
|
|
207
|
-
5.
|
|
209
|
+
1. **At any new task start, always call `recall` first** (even briefly)
|
|
210
|
+
2. **Before touching the same file, verify history via `recall_file`**
|
|
211
|
+
3. **Prefer `read_smart` over `Read` for larger files**
|
|
212
|
+
4. **When an error occurs, record a `caveat` immediately** (on the spot โ don't defer)
|
|
213
|
+
5. **When the user is surprised or says "interesting", record a `learning`**
|
|
208
214
|
|
|
209
|
-
### โ
|
|
215
|
+
### โ Don't
|
|
210
216
|
|
|
211
|
-
1. โ
|
|
212
|
-
2. โ
|
|
213
|
-
3. โ `Read`
|
|
214
|
-
4. โ
|
|
215
|
-
5. โ
|
|
217
|
+
1. โ Start a task without recalling first
|
|
218
|
+
2. โ Solve an error on the spot without recording โ future you (or another agent) will hit the same failure
|
|
219
|
+
3. โ Use `Read` everywhere instead of `read_smart` (wastes tokens)
|
|
220
|
+
4. โ Write caveats in a flippant tone โ preserve them seriously
|
|
221
|
+
5. โ Skip `consolidate` during long-running work โ run it weekly
|
|
216
222
|
|
|
217
223
|
---
|
|
218
224
|
|
|
219
|
-
## ๐ Consolidate โ
|
|
225
|
+
## ๐ Consolidate โ periodic memory tidy-up
|
|
220
226
|
|
|
221
|
-
|
|
227
|
+
When memory has grown (rough guideline: DB > 20MB, memories > 15,000):
|
|
222
228
|
|
|
223
229
|
```
|
|
224
230
|
mcp__linksee__consolidate({
|
|
@@ -227,142 +233,142 @@ mcp__linksee__consolidate({
|
|
|
227
233
|
})
|
|
228
234
|
```
|
|
229
235
|
|
|
230
|
-
|
|
236
|
+
This clusters cold, low-importance memories older than 7 days โ compresses them into a single `learning`-layer entry โ deletes originals.
|
|
231
237
|
|
|
232
|
-
|
|
238
|
+
**`caveat` memories and active `goal` memories are never consolidated away.** Equivalent to sleep-time memory reorganization.
|
|
233
239
|
|
|
234
240
|
---
|
|
235
241
|
|
|
236
|
-
## ๐งญ Skill
|
|
242
|
+
## ๐งญ Skill firing scenarios
|
|
237
243
|
|
|
238
|
-
### Case A
|
|
244
|
+
### Case A โ Returning to a project
|
|
239
245
|
|
|
240
|
-
|
|
246
|
+
User: "Today I'm back on the XYZ project"
|
|
241
247
|
|
|
242
248
|
```
|
|
243
249
|
1. recall({ query: "XYZ", max_tokens: 2500 })
|
|
244
|
-
2.
|
|
245
|
-
3.
|
|
246
|
-
4.
|
|
250
|
+
2. Review returned caveat / learning / goal
|
|
251
|
+
3. Tell user "Picking up from last time..." with a one-line status
|
|
252
|
+
4. Resume work grounded in that context
|
|
247
253
|
```
|
|
248
254
|
|
|
249
|
-
### Case B
|
|
255
|
+
### Case B โ Dรฉjร -vu error
|
|
250
256
|
|
|
251
|
-
|
|
257
|
+
User: "Wait, I feel like I've seen this error before..."
|
|
252
258
|
|
|
253
259
|
```
|
|
254
|
-
1. recall({ query: "
|
|
255
|
-
2.
|
|
256
|
-
3.
|
|
257
|
-
4. workaround
|
|
260
|
+
1. recall({ query: "<core keywords of the error message>", max_tokens: 1000 })
|
|
261
|
+
2. Pull workaround from past caveat
|
|
262
|
+
3. Reply: "Last time (DATE), we hit the same error and solved it with X."
|
|
263
|
+
4. Apply the workaround
|
|
258
264
|
```
|
|
259
265
|
|
|
260
|
-
### Case C
|
|
266
|
+
### Case C โ Pre-edit check
|
|
261
267
|
|
|
262
|
-
|
|
268
|
+
User: "Fix server.ts"
|
|
263
269
|
|
|
264
270
|
```
|
|
265
271
|
1. recall_file({ path_substring: "server.ts" })
|
|
266
|
-
2.
|
|
267
|
-
3.
|
|
268
|
-
4.
|
|
269
|
-
5.
|
|
272
|
+
2. Review past edit frequency and reasons
|
|
273
|
+
3. Report: "This file has been edited N times. Last edit was to <reason>."
|
|
274
|
+
4. Perform the edit in that context
|
|
275
|
+
5. After editing, record success / failure via implementation layer
|
|
270
276
|
```
|
|
271
277
|
|
|
272
|
-
### Case D
|
|
278
|
+
### Case D โ Decision made
|
|
273
279
|
|
|
274
|
-
|
|
280
|
+
User: "Alright, let's switch to Sonnet"
|
|
275
281
|
|
|
276
282
|
```
|
|
277
283
|
1. remember({
|
|
278
|
-
entity_name: "
|
|
284
|
+
entity_name: "<project>",
|
|
279
285
|
entity_kind: "project",
|
|
280
286
|
layer: "learning",
|
|
281
|
-
content: '{"at":"...", "learned":"
|
|
287
|
+
content: '{"at":"...", "learned":"This project uses Sonnet", "prior_belief":"Was using Opus"}',
|
|
282
288
|
importance: 0.8
|
|
283
289
|
})
|
|
284
|
-
2.
|
|
285
|
-
3.
|
|
290
|
+
2. Brief confirmation: "Recorded."
|
|
291
|
+
3. From here, proceed assuming Sonnet
|
|
286
292
|
```
|
|
287
293
|
|
|
288
|
-
### Case E
|
|
294
|
+
### Case E โ End of long session
|
|
289
295
|
|
|
290
|
-
|
|
296
|
+
User: "That's it for today"
|
|
291
297
|
|
|
292
298
|
```
|
|
293
|
-
1.
|
|
294
|
-
-
|
|
295
|
-
-
|
|
296
|
-
-
|
|
297
|
-
2.
|
|
298
|
-
3.
|
|
299
|
+
1. Record today's highlights via remember:
|
|
300
|
+
- Major decisions โ learning layer
|
|
301
|
+
- Failures hit โ caveat layer
|
|
302
|
+
- Finished deliverables โ implementation.success
|
|
303
|
+
2. Report: "Recorded. Retrievable via recall next session."
|
|
304
|
+
3. Optionally suggest: consolidate({scope:"session", min_age_days: 14})
|
|
299
305
|
```
|
|
300
306
|
|
|
301
|
-
### Case F
|
|
307
|
+
### Case F โ User explicitly says "remember this"
|
|
302
308
|
|
|
303
|
-
|
|
309
|
+
User: "Remember this: DocuSign is more stable than CloudSign"
|
|
304
310
|
|
|
305
311
|
```
|
|
306
312
|
1. remember({
|
|
307
|
-
entity_name: "
|
|
313
|
+
entity_name: "CloudSign vs DocuSign",
|
|
308
314
|
entity_kind: "concept",
|
|
309
315
|
layer: "caveat",
|
|
310
|
-
content: '{"rule_or_warning":"
|
|
311
|
-
importance: 0.9 //
|
|
316
|
+
content: '{"rule_or_warning":"CloudSign (61% success) is less reliable than DocuSign-JP (100%). Recommend DocuSign when advising customers."}',
|
|
317
|
+
importance: 0.9 // user-explicit instruction = high priority
|
|
312
318
|
})
|
|
313
|
-
2.
|
|
319
|
+
2. Confirm: "Recorded. Since it's in the caveat layer, it won't be forgotten."
|
|
314
320
|
```
|
|
315
321
|
|
|
316
322
|
---
|
|
317
323
|
|
|
318
|
-
## ๐
|
|
324
|
+
## ๐ Privacy (when the user asks)
|
|
319
325
|
|
|
320
|
-
linksee-memory
|
|
321
|
-
- DB: `~/.linksee-memory/memory.db`
|
|
322
|
-
-
|
|
323
|
-
-
|
|
326
|
+
linksee-memory is **fully local**:
|
|
327
|
+
- DB: `~/.linksee-memory/memory.db` (inside the user's PC)
|
|
328
|
+
- External transmission: none (telemetry is opt-in, OFF by default)
|
|
329
|
+
- Backup: a simple file copy is sufficient
|
|
324
330
|
|
|
325
|
-
|
|
326
|
-
|
|
331
|
+
If the user asks "does our data leave my machine?", answer:
|
|
332
|
+
"**By default, nothing leaves.** Unless you explicitly enable telemetry, everything is in a local DB. A copy of `~/.linksee-memory/memory.db` is the only backup you need."
|
|
327
333
|
|
|
328
334
|
---
|
|
329
335
|
|
|
330
|
-
## ๐ KanseiLink Skill
|
|
336
|
+
## ๐ Pairing with KanseiLink Skill
|
|
331
337
|
|
|
332
|
-
KanseiLink skill
|
|
338
|
+
The KanseiLink skill and linksee-memory skill **work best together**:
|
|
333
339
|
|
|
334
340
|
```
|
|
335
|
-
|
|
341
|
+
User: "Create an invoice via freee"
|
|
336
342
|
โ
|
|
337
|
-
[linksee-memory skill
|
|
338
|
-
โ
|
|
339
|
-
โ
|
|
343
|
+
[linksee-memory skill fires] recall({query: "freee"})
|
|
344
|
+
โ past caveat: "fetch company_id first"
|
|
345
|
+
โ past learning: "OAuth 24h refresh required"
|
|
340
346
|
โ
|
|
341
|
-
[kansei-link skill
|
|
342
|
-
โ freee verified
|
|
343
|
-
โ get_service_tips
|
|
347
|
+
[kansei-link skill fires] search_services({intent: "invoice"})
|
|
348
|
+
โ freee verified, trust 0.9
|
|
349
|
+
โ get_service_tips reveals pitfalls
|
|
344
350
|
โ
|
|
345
|
-
|
|
351
|
+
Now you have both bodies of knowledge before starting
|
|
346
352
|
```
|
|
347
353
|
|
|
348
|
-
**KanseiLink =
|
|
354
|
+
**KanseiLink = collective knowledge about external SaaS / linksee-memory = collective knowledge about your own past**. Two wheels of the same cart.
|
|
349
355
|
|
|
350
356
|
---
|
|
351
357
|
|
|
352
|
-
## ๐
|
|
358
|
+
## ๐ Precision grows with usage
|
|
353
359
|
|
|
354
|
-
|
|
|
360
|
+
| Moment | recall precision | Why |
|
|
355
361
|
|---|---|---|
|
|
356
|
-
| Day 1 |
|
|
357
|
-
| Week 1 |
|
|
358
|
-
| Month 1 |
|
|
359
|
-
| Month 3+ |
|
|
362
|
+
| Day 1 | low (little data) | Stop hook is still collecting |
|
|
363
|
+
| Week 1 | medium | thousands of memories, FTS5 kicks in |
|
|
364
|
+
| Month 1 | high | heat_score stabilizes, important memories surface |
|
|
365
|
+
| Month 3+ | strongest | consolidate has run, learnings crystallized |
|
|
360
366
|
|
|
361
|
-
|
|
367
|
+
**"Gets smarter with use"** โ time is on your side. Today's record is read by tomorrow's you.
|
|
362
368
|
|
|
363
369
|
---
|
|
364
370
|
|
|
365
|
-
|
|
366
|
-
*Stop hook
|
|
367
|
-
*MCP Registry
|
|
371
|
+
*This skill runs on top of linksee-memory MCP v0.2.0+.*
|
|
372
|
+
*Auto-write via Stop hook, explicit read via recall.*
|
|
373
|
+
*Listed in MCP Official Registry, PulseMCP, mcpservers.org, Glama.*
|
|
368
374
|
*MIT License โ Synapse Arrows PTE. LTD.*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linksee-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"mcpName": "io.github.michielinksee/linksee-memory",
|
|
5
5
|
"description": "Local-first agent memory MCP โ cross-agent brain with 6-layer structured memory + token-saving file diff cache",
|
|
6
6
|
"type": "module",
|