linksee-memory 0.17.1 → 0.18.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 +126 -822
- package/dist/bin/import-sessions.js +13 -3
- package/dist/bin/migrate-legacy.d.ts +33 -0
- package/dist/bin/migrate-legacy.js +501 -0
- package/dist/bin/runtime.d.ts +52 -0
- package/dist/bin/runtime.js +381 -0
- package/dist/bin/setup.js +1 -1
- package/dist/bin/sync-session.js +1 -1
- package/dist/db/migrate.d.ts +53 -2
- package/dist/db/migrate.js +106 -37
- package/dist/lib/hook-runtime.js +9 -4
- package/dist/lib/supersede.d.ts +35 -0
- package/dist/lib/supersede.js +130 -0
- package/dist/lib/test-faults.d.ts +3 -0
- package/dist/lib/test-faults.js +30 -0
- package/dist/mcp/server.js +187 -16
- package/dist/skill/SKILL.md +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,603 +1,108 @@
|
|
|
1
1
|
# linksee-memory
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
>
|
|
5
|
-
> **Linksee Memory lets you hand a project over — to your next session, to Cursor or Codex, to the person after you — with the reasons attached.** Record a decision once (`remember({ content, anchor: {} })`) and it comes back *before* the agent acts on it: re-injected on session start and ahead of every Edit / Write / Bash that touches it. Change your mind on the record and it stops nagging; leave it and it keeps the next agent from repeating last week's mistake.
|
|
6
|
-
>
|
|
7
|
-
> Underneath: **drift detection** across every project you run in parallel — which ones quietly left their goal (🔴), which were checked and hold (🔵), which nobody has looked at yet (⚫). One local SQLite file that **Claude Code, Cursor, Windsurf, OpenAI Codex and Gemini CLI** all read. Nothing leaves your machine.
|
|
8
|
-
>
|
|
9
|
-
> `npx -y linksee-memory setup` — one command, on in every repo.
|
|
3
|
+
A local MCP memory server: one SQLite file on your machine that Claude Code, Cursor, Windsurf, OpenAI Codex and Gemini CLI all read and write. No account, no credit card, no cloud, no API key. The server makes no network calls; telemetry is opt-in and off by default.
|
|
10
4
|
|
|
11
|
-
|
|
12
|
-
[](./LICENSE)
|
|
13
|
-
[](https://registry.modelcontextprotocol.io/)
|
|
14
|
-
[](https://glama.ai/mcp/servers/michielinksee/linksee-memory)
|
|
15
|
-
|
|
16
|
-
🌐 **Landing page**: [linksee.app](https://linksee.app) (includes non-developer onboarding for Claude Desktop / Cursor / Claude Code / OpenAI Codex / Gemini CLI)
|
|
17
|
-
📖 **Docs**: [docs.linksee.app](https://docs.linksee.app) — full reference: the product map & drift, install, and every tool
|
|
18
|
-
|
|
19
|
-
<!-- releases: tag-driven, published from CI via npm trusted publishing (OIDC).
|
|
20
|
-
See .github/workflows/publish.yml — no token, no OTP, provenance attached automatically. -->
|
|
21
|
-
|
|
22
|
-
## Questions this answers
|
|
23
|
-
|
|
24
|
-
These are the questions people actually type — measured, verbatim (2026-09-04). If yours is here, this is the answer.
|
|
25
|
-
|
|
26
|
-
**Claude Code forgets everything when I start a new session. How do I make it remember decisions across sessions?**
|
|
27
|
-
Run `npx -y linksee-memory setup`. Every new session opens with `recall()` — a brief of what needs attention, where you are, what's unresolved — and your locked decisions are re-injected before the agent acts. Nothing to re-explain.
|
|
28
|
-
|
|
29
|
-
**Claude Codeがセッションをまたぐと過去の経緯を忘れてしまいます。記憶を持たせる方法を教えてください。**
|
|
30
|
-
`npx -y linksee-memory setup` の一回で入ります。新しいセッションは `recall()` の brief(注意すべきこと・いまどこか・未解決)から始まり、固定した決定は行動の直前に再注入されます。説明し直す必要はありません。
|
|
31
|
-
|
|
32
|
-
**What is the best MCP server for persistent memory across AI coding agents?**
|
|
33
|
-
Honest answer: if "remember across sessions" is all you need, a `CLAUDE.md` is enough — we measured it. Linksee is for the three moments it isn't: right before a mistake, when you change your mind, and when you run many projects and need to see which one drifted.
|
|
34
|
-
|
|
35
|
-
**AIコーディングエージェント用の記憶MCPサーバーでおすすめはありますか?**
|
|
36
|
-
正直に言うと、「セッションを跨いで覚える」だけなら `CLAUDE.md` で足ります(実測しました)。Linksee が要るのは、間違いかけたとき・方針を変えたとき・並行案件のどれが外れたかを知りたいとき、の3場面です。
|
|
37
|
-
|
|
38
|
-
**I want one shared memory between Claude Code, Cursor, and OpenAI Codex. What tools exist for that?**
|
|
39
|
-
One SQLite file. Claude Code, Cursor, Windsurf, OpenAI Codex and Gemini CLI all read and write the same memory — a decision made in one shows up in the others.
|
|
40
|
-
|
|
41
|
-
**Claude CodeとCursorとCodexで同じ記憶を共有したいのですが、どうすればいいですか?**
|
|
42
|
-
SQLite ファイル1つを全員で読みます。Claude Code / Cursor / Windsurf / Codex / Gemini CLI のどこで決めた決定も、他のエージェントの行動の直前に出てきます。
|
|
43
|
-
|
|
44
|
-
**My AI agent keeps re-implementing things we already decided against. How can I detect that a codebase has drifted from past decisions?**
|
|
45
|
-
Declare the decision (`remember({ content, anchor: { violation_signal: [...] } })`). The guard then warns — or blocks, if you hardened it — the moment an edit contradicts it, and `drift_status` shows every decision that reality has quietly left.
|
|
46
|
-
|
|
47
|
-
**過去に決めた設計方針とコードがずれていないかを検出できるツールはありますか?**
|
|
48
|
-
決定を宣言しておくと(`remember({ content, anchor: {...} })`)、それに反する編集の直前に警告(hardened なら拒否)が出ます。`drift_status` は「宣言と現実がずれた決定」を証拠つきで一覧します。
|
|
49
|
-
|
|
50
|
-
**Is there a local-first, self-hosted alternative to Mem0 for agent memory?**
|
|
51
|
-
Yes. No account, no API key, no cloud — one local file, MIT licensed. `npx -y linksee-memory setup` and it's on.
|
|
52
|
-
|
|
53
|
-
**Mem0 vs Zep vs Letta for a coding agent's long-term memory — which should I pick?**
|
|
54
|
-
We installed them and ran one scenario across all of them. Storing and recalling a decision: everyone passes. The difference appears *before a mistake* and *when you change your mind* — Linksee is built for those two moments; the others leave them to you.
|
|
55
|
-
|
|
56
|
-
**How do I stop Claude Code from repeating the same mistake it made last week?**
|
|
57
|
-
Record it as a caveat (`remember({ content, layer: 'caveat' })`). Caveats are protected from forgetting and come back when the same ground is touched again — and if you anchor it, the guard stops the repeat before it lands.
|
|
58
|
-
|
|
59
|
-
**開発の意思決定履歴をMCPサーバーで残しておく定番のやり方はありますか?**
|
|
60
|
-
`remember({ content, anchor: {} })` の1回で、記録と強制が同時に入ります。`drift_status` がその台帳で、各決定が いま守られているか(🔵)・ずれているか(🔴)・誰も確かめていないか(⚫)を示します。
|
|
61
|
-
|
|
62
|
-
## 🪄 Three spells to remember
|
|
63
|
-
|
|
64
|
-
| Say this | What happens |
|
|
65
|
-
|---|---|
|
|
66
|
-
| **"use linksee"** | Recalls relevant memories before acting |
|
|
67
|
-
| **"linksee this"** | Saves the decision / lesson right now |
|
|
68
|
-
| **"what's drifting?"** | Reconciles reality against your locked decisions |
|
|
69
|
-
|
|
70
|
-
> Make it automatic: add **"Use Linksee Memory"** to your system prompt / `CLAUDE.md`.
|
|
5
|
+
It is for handing a project over — to your next session, to another client, to the person after you — with the reasons attached. Every client can save and search the memory. In Claude Code, hooks also bring a recorded decision back at session start and before an edit. Drift detection shows which recorded decisions the code has since left.
|
|
71
6
|
|
|
72
|
-
|
|
7
|
+
Needs Node.js 20 or later, and Claude Code or Codex to try it (either one is enough).
|
|
73
8
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-

|
|
77
|
-
|
|
78
|
-
**The 30-second demo above:** the README says `--export`. The code doesn't. Linksee catches it — and shows what else a change would touch.
|
|
9
|
+
## Install
|
|
79
10
|
|
|
80
11
|
```bash
|
|
81
|
-
npx -y linksee-memory
|
|
82
|
-
npx -y linksee-memory
|
|
83
|
-
npx -y linksee-memory map affects readme # changing the README also touches docs, the CLI help, and the npm listing
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
→ see [The Map](#the-map) for the full flow.
|
|
87
|
-
|
|
88
|
-
## 📣 As featured on
|
|
89
|
-
|
|
90
|
-
- **Zenn**: [あなたの Claude Code、 実は前回のセッションを完全に忘れている](https://zenn.dev/kanseilink/articles/linksee-memory-claude-code-recall-20260508) — 73 ♡ on Zenn, **165+ users on Hatena Bookmark**, picked up by tech blogs + YouTube shorts (May 2026)
|
|
91
|
-
- **Zenn**: [あなたの MCP server、 実は Tools しか使ってない (5 blocks 全実装 / v0.3.0)](https://zenn.dev/kanseilink/articles/linksee-memory-mcp-five-blocks-20260507) — the 1% of MCP servers that implement all 5 blocks
|
|
92
|
-
- **Zenn**: [あなたの Claude memory、 実は Claude にしか残らない (5 LLM 横断する方法)](https://zenn.dev/kanseilink/articles/linksee-memory-claude-cross-llm-20260511) — cross-LLM memory pattern (May 12, 2026)
|
|
93
|
-
- **Zenn**: [Glama listing で 3 週間止まった話 (5 つの罠と解決策)](https://zenn.dev/michielinksee/articles/linksee-memory-mcp-publish-glama-traps-20260506) — npm + Glama deployment retrospective
|
|
94
|
-
|
|
95
|
-
> 「Cordex/Cursor/Code/Gemini 全部につなげられるから、 横断的にできてる MCP ってところがこれのすごいところ」
|
|
96
|
-
> — [Hatena Bookmark, May 2026](https://b.hatena.ne.jp/entry/s/zenn.dev/kanseilink/articles/linksee-memory-claude-code-recall-20260508) (165+ users)
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## 🎬 See it in action
|
|
101
|
-
|
|
102
|
-
**Drift, caught.** Decisions don't survive session boundaries — but their consequences do. Ask any session:
|
|
103
|
-
|
|
12
|
+
npx -y linksee-memory setup # Claude Code: MCP server, skill, hooks
|
|
13
|
+
codex mcp add linksee -- npx -y linksee-memory # Codex: the same memory
|
|
104
14
|
```
|
|
105
|
-
You: What's drifting right now?
|
|
106
|
-
Agent: [calls drift_status]
|
|
107
15
|
|
|
108
|
-
|
|
16
|
+
One command for Claude Code. `setup --dry-run` prints what it would change. It edits `~/.claude/settings.json`, so the hooks apply in every repo, and keeps the old file as `settings.json.bak-<timestamp>` ([what it writes](#what-setup-writes)).
|
|
109
17
|
|
|
110
|
-
|
|
111
|
-
⚪ HELD — "Focus on 4 areas: Recipe layer, agent-native API,
|
|
112
|
-
Japanese market, Agent Insights"
|
|
113
|
-
↻ Reopens 2026-07-04
|
|
18
|
+
## First round trip
|
|
114
19
|
|
|
115
|
-
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**The memory underneath.** Drift detection only works because the *why* survives the session boundary:
|
|
20
|
+
A new install has an empty memory, so "how did we solve this before?" finds nothing yet. Try this instead:
|
|
119
21
|
|
|
120
|
-
|
|
22
|
+
1. In Claude Code or Codex, say: *"Remember: in this repo we decided to use X, because Y. Use Linksee."*
|
|
23
|
+
2. Open a **new** session — in either one — and ask: *"What did we decide about X? Use Linksee."*
|
|
24
|
+
3. Two repos: record a decision in repo A, then in repo B (e.g. Codex) ask the same. It **does** come back — the memory is per machine, not per repo — labelled `entity: repo-a` and `by: <client>`; `entity_name` on the recall narrows by a part of the entity name (`repo-a` also matches `repo-a-backup`).
|
|
25
|
+
4. Reverse it: `remember` the new decision with `supersedes: <old memory_id>`. `recall` then shows only the new one (`supersedes #<id>`); `include_superseded: true` shows both.
|
|
121
26
|
|
|
122
|
-
|
|
123
|
-
You: We deployed last week but it crashed. How did we fix it?
|
|
124
|
-
Claude: I don't have access to previous sessions. Can you describe
|
|
125
|
-
what happened and walk me through the problem?
|
|
126
|
-
|
|
127
|
-
[30 minutes of log-spelunking and re-explanation]
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**With linksee-memory** — Same question, different outcome:
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
You: We deployed last week but it crashed. How did we fix it?
|
|
134
|
-
Claude: Let me check my caveats...
|
|
27
|
+
## What it does not do
|
|
135
28
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
29
|
+
- Reminders and blocks before an edit are Claude Code hooks. Cursor, Windsurf, Codex and Gemini CLI share the memory but get no warning before an edit.
|
|
30
|
+
- Saving every session automatically is also Claude Code only. Other clients save when the agent calls `remember`.
|
|
31
|
+
- The memory is shared on one machine. There is no sync to another machine; to hand it over, copy `~/.linksee-memory/` (with every client closed).
|
|
32
|
+
- A database from a very early version (schema 1–5) is refused without being changed. Close every client and keep them closed while it runs, then `npx -y linksee-memory@0.17.2 migrate --dry` and `npx -y linksee-memory@0.17.2 migrate`: it migrates a copy and moves the original files, as one set, into `memory.db.pre-migrate-<time>/` ([details and how to go back](docs/troubleshooting.md)).
|
|
139
33
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
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.
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## 🔍 Drift Detection — "Intent Datadog"
|
|
151
|
-
|
|
152
|
-
Most teams make decisions, then forget them. The agent from last week decided "we'll use FTS5 instead of vector search" — but this week a new session installs `pgvector` without knowing why that was rejected. **That's drift.** Not a bug. Not malice. Just forgotten context.
|
|
153
|
-
|
|
154
|
-
Memory tools remember what you did. Nothing notices when you drift from what you decided — that's the layer Linksee Memory adds. Think **"Datadog for product decisions"**: unaccounted divergences surface as drift, intentional evolution (recorded as supersede/fix) stays quiet.
|
|
155
|
-
|
|
156
|
-
### How it works
|
|
157
|
-
|
|
158
|
-
1. **Declare** decisions as anchors: `declare_anchor({ kind: "decision", statement: "We use FTS5, not vector search", violation_signal: ["pgvector", "embedding"] })`
|
|
159
|
-
2. **The engine detects** when committed code reality diverges from these anchors
|
|
160
|
-
3. **State derivation** classifies each anchor:
|
|
161
|
-
- 🔴 **Drift** — reality diverges with no recorded resolution
|
|
162
|
-
- 🟡 **Review** — a soft signal awaits your decision
|
|
163
|
-
- ⚪ **Held** — you acknowledged the gap, parked it with a review date
|
|
164
|
-
- 🔵 **Aligned** — reality matches intent, or a recorded resolution explains the change
|
|
165
|
-
4. **Resolve** with `fix`, `supersede`, `acknowledge`, or `dismiss` — plus two gates: `harden` (PreToolUse will block) and `soften` (back to a warning)
|
|
166
|
-
|
|
167
|
-
The **make-or-break rule**: a divergence accounted for by a recorded resolution (supersede/fix/acknowledge) is NOT drift. Only unaccounted gaps are flagged. This means intentional evolution stays quiet while silent abandonment gets caught.
|
|
168
|
-
|
|
169
|
-
### 4-species taxonomy
|
|
170
|
-
|
|
171
|
-
Anchors are classified into four species with different display formats:
|
|
172
|
-
|
|
173
|
-
| Species | Icon | Display Format | Example |
|
|
174
|
-
|---|---|---|---|
|
|
175
|
-
| Hypothesis | 🧪 | Decision Card (journal format) | "We'll launch English-first on HN" |
|
|
176
|
-
| Constraint | 🔒 | Rule (pass/fail checklist) | "All writes go through remember()" |
|
|
177
|
-
| Commitment | 🔁 | Heartbeat (alive/dead) | "Ship a new version every week" |
|
|
178
|
-
| Source of Truth | 📍 | Reference (stable anchor) | "MCP server runs on stdio, single SQLite" |
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
<a id="the-map"></a>
|
|
183
|
-
|
|
184
|
-
## 🗺️ The Map — `linksee-memory map`
|
|
185
|
-
|
|
186
|
-
Drift detection (above) checks individual anchors. The **Map** lifts it to the whole product: a `map.yaml` describing how value reaches your user (`discover → understand → try → adopt → retain → monetize → expand`), with typed dependencies between the pieces — README, npm listing, onboarding, the engine that powers them. The reconciler checks that map against your real code, and the CLI answers the question an engineer actually has:
|
|
187
|
-
|
|
188
|
-
> *I'm touching this file — where is it on the map, and what else must move?*
|
|
189
|
-
|
|
190
|
-
**1. Where am I?** — locate a file (or, with no argument, infer from your recent edits):
|
|
191
|
-
|
|
192
|
-
```
|
|
193
|
-
$ npx -y linksee-memory map where README.md
|
|
194
|
-
"README.md" belongs to this Map node:
|
|
195
|
-
|
|
196
|
-
readme [understand] convergence
|
|
197
|
-
changes ripple to:
|
|
198
|
-
must fix together (hard): lp, docs-site
|
|
199
|
-
should align (soft): onboarding, client-configs
|
|
200
|
-
fyi (may ripple): telemetry-contract
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
The blast radius is **graded** — `must fix together` vs `should align` vs `fyi` — so a wide ripple isn't flat noise.
|
|
204
|
-
|
|
205
|
-
**2. Why is it in this state?** — the diagnosis, with file:line evidence:
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
$ npx -y linksee-memory map explain readme
|
|
209
|
-
|
|
210
|
-
STATUS
|
|
211
|
-
declared: healthy (active)
|
|
212
|
-
reality: implemented / matches
|
|
213
|
-
verdict: declared and reality agree (verified)
|
|
214
|
-
|
|
215
|
-
EVIDENCE
|
|
216
|
-
✓ README's Tools section lists where_am_i
|
|
217
|
-
README.md:424 — found "where_am_i" in section "Tools"
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Declared state and the reality verdict are shown **separately** — a hand-declared `suspect` the scanner refutes reads as *"declared suspect, refuted by reality (→ convergence)"*, not a confusing mix.
|
|
221
|
-
|
|
222
|
-
**3. Whole-project triage:** `npx -y linksee-memory map status` — a health %, what is *fixable now in code* vs *external checks*, and any deferral with no expiry (so "accounted-for" can't quietly become a drift graveyard).
|
|
223
|
-
|
|
224
|
-
**How it works**
|
|
225
|
-
- **`map.yaml`** (repo root) is the desired-state source of truth: a journey spine × surface/implementation layers × typed edges (`must-stay-consistent-with` / `should-align-with` / `realizes`).
|
|
226
|
-
- **`reconcile`** checks each node's declared `reality` against the code (`signal` / `regex` / `section_contains` / file checks) and overlays a verdict — reality overrides what you hand-declared, with evidence.
|
|
227
|
-
- `where_am_i` is also an **MCP tool**, so a coding agent can re-anchor itself mid-task.
|
|
228
|
-
|
|
229
|
-
Commands: `where` · `affects` · `explain` · `status` · `next` · `reconcile` · `inspect --json` · `blueprint`. Add `--lang ja` for Japanese labels.
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
<a id="reinjection-guard"></a>
|
|
234
|
-
|
|
235
|
-
## 🛡 Re-injection Guard — enforce decisions *before* the action
|
|
236
|
-
|
|
237
|
-
Drift detection (above) is **post-hoc** — it tells you reality diverged *after* the change lands. The re-injection guard is the **pre-action** half: it re-surfaces the decision you locked **before** the agent runs the tool that would break it.
|
|
238
|
-
|
|
239
|
-
It exists for one specific, infuriating failure mode ([anthropics/claude-code#15443](https://github.com/anthropics/claude-code/issues/15443)): *"Claude read the rule, understood it, and still used `cp`."* Having the rule in context isn't enough — so the guard runs **outside the agent's volition**, as a Claude Code hook:
|
|
240
|
-
|
|
241
|
-
| Hook event | Fires on | What it does |
|
|
242
|
-
|---|---|---|
|
|
243
|
-
| **`PreToolUse`** | `Edit` / `Write` / `Bash` | Checks the pending action against your accepted anchors. A `gate_mode:'hard'` contradiction is **denied**; a softer match re-injects the decision as a reminder; no match → nothing happens. |
|
|
244
|
-
| **`SessionStart`** | `startup` / `resume` / `compact` | Replays your locked decisions + open forks into the fresh session — killing the "groundhog day" amnesia where a new agent repeats last week's call. |
|
|
245
|
-
|
|
246
|
-
It is **fail-open by construction**: any parse / DB / logic error surfaces nothing and lets the action through. The *only* thing that ever blocks is an explicit `hard` contradiction on a decision **you** declared.
|
|
247
|
-
|
|
248
|
-
### Enable it
|
|
249
|
-
|
|
250
|
-
`npx -y linksee-memory setup` wires this into `~/.claude/settings.json` (Step 4), so it is on in **every** repo — the same scope your memory already lives at. One SQLite file holds the anchors for all your projects; enforcing them per-repo meant declaring a decision once and having it enforced nowhere.
|
|
251
|
-
|
|
252
|
-
- `--project-guard` — this repo only, the old behaviour
|
|
253
|
-
- `--no-guard` — skip it
|
|
254
|
-
|
|
255
|
-
Anchors with `affects` globs fire only on matching paths; an unscoped anchor fires on its own `detect_terms` / `violation_signal`. Nothing is ever **blocked** unless you explicitly hardened it (`resolve_drift(action:'harden')`) — everything else re-injects the decision as context.
|
|
256
|
-
|
|
257
|
-
To wire it by hand instead, drop this block into `.claude/settings.json` (project root, or `~/.claude/settings.json` for every repo). The `npx -y` form below needs no install, but costs several seconds per call (7.4–8.6 s measured on Windows, close to the 8 s `PreToolUse` timeout — a timed-out guard simply does not fire). `setup` writes a direct `node` call instead; you can do the same with `"<path to node>" "<package>/dist/bin/guard-hook.js"` (paths quoted; Claude Code runs hooks through cmd.exe on Windows and sh elsewhere, and a path containing `$`, a backtick, `%` or `"` cannot be quoted safely — setup keeps the npx form for those):
|
|
258
|
-
|
|
259
|
-
```json
|
|
260
|
-
{
|
|
261
|
-
"hooks": {
|
|
262
|
-
"SessionStart": [
|
|
263
|
-
{
|
|
264
|
-
"matcher": "startup|resume|compact",
|
|
265
|
-
"hooks": [
|
|
266
|
-
{ "type": "command", "command": "npx -y linksee-memory guard", "timeout": 15 }
|
|
267
|
-
]
|
|
268
|
-
}
|
|
269
|
-
],
|
|
270
|
-
"PreToolUse": [
|
|
271
|
-
{
|
|
272
|
-
"matcher": "Edit|Write|Bash",
|
|
273
|
-
"hooks": [
|
|
274
|
-
{ "type": "command", "command": "npx -y linksee-memory guard", "timeout": 8 }
|
|
275
|
-
]
|
|
276
|
-
}
|
|
277
|
-
]
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
Where it applies is the settings file it lives in: `~/.claude/settings.json` (what `setup` writes) covers every repo; a project's `.claude/settings.json` (`setup --project-guard`) covers that repo only. Declare what it should watch with `declare_anchor(...)`; set `card_policy.gate_mode:'hard'` on an anchor to make a contradiction **block** instead of just warn (the soft default only re-injects). Anchors that are stale (`at_risk`), superseded, or card-disabled never gate.
|
|
283
|
-
|
|
284
|
-
> Developing linksee-memory itself? The repo dogfoods the guard via a (gitignored) `.claude/settings.json` that points at the local build (`node ${CLAUDE_PROJECT_DIR}/dist/bin/guard-hook.js`) so it runs against your uncommitted changes. End-user projects should use the published `npx -y linksee-memory guard` form above.
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
## What it does
|
|
289
|
-
|
|
290
|
-
Most "agent memory" services (Mem0, Letta, Zep) save a flat list of facts. Then the agent looks at "edited file X 30 times" and has no idea why. And none of them notice when this week's work contradicts last week's decision. **linksee-memory keeps the WHY — and watches the drift.**
|
|
291
|
-
|
|
292
|
-
It is a Model Context Protocol (MCP) server with **7 tools** (six for memory and drift, plus the optional `share_draft`) that gives any AI agent structured memory + drift detection:
|
|
293
|
-
|
|
294
|
-
| | Mem0 / Letta / Zep | Claude Code auto-memory | linksee-memory |
|
|
295
|
-
|---|---|---|---|
|
|
296
|
-
| **Drift detection** | ❌ | ❌ | ✅ intent ↔ reality divergence tracking |
|
|
297
|
-
| Cross-agent | △ (cloud) | ❌ Claude only | ✅ single SQLite file |
|
|
298
|
-
| 6-layer WHY structure | ❌ flat | ❌ flat markdown | ✅ goal / context / emotion / impl / caveat / learning |
|
|
299
|
-
| File diff cache | ❌ | ❌ | ✅ AST-aware, 50-99% token savings on re-reads |
|
|
300
|
-
| Active forgetting | △ | ❌ | ✅ Ebbinghaus curve, caveat layer protected |
|
|
301
|
-
| Local-first / private | ❌ | ✅ | ✅ |
|
|
302
|
-
|
|
303
|
-
## Four pillars
|
|
304
|
-
|
|
305
|
-
1. **Drift detection** — declare decisions as anchors, then the engine automatically detects when committed reality diverges from stated intent. Think "Datadog for product decisions" — unaccounted divergences surface as drift, intentional evolution (recorded as supersede/fix) stays quiet.
|
|
306
|
-
2. **Cross-agent portability** — single SQLite file at `~/.linksee-memory/memory.db`. Same brain for Claude Code, Cursor, Windsurf, OpenAI Codex, Gemini CLI.
|
|
307
|
-
3. **WHY-first structured memory** — six explicit layers (`goal` / `context` / `emotion` / `implementation` / `caveat` / `learning`). Solves "flat fact memory is useless without goals".
|
|
308
|
-
4. **Token savings** via `read_smart` — sha256 + AST/heading/indent chunking. Re-reads return only diffs. **Measured 86% saved on a typical TS file edit, 99% saved on unchanged re-reads.**
|
|
309
|
-
|
|
310
|
-
## 🧠 The 6-layer structure
|
|
311
|
-
|
|
312
|
-
```
|
|
313
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
314
|
-
│ 🎯 goal ← what the user is working toward │
|
|
315
|
-
├─────────────────────────────────────────────────────────────┤
|
|
316
|
-
│ 🧭 context ← why this, why now — constraints, people │
|
|
317
|
-
├─────────────────────────────────────────────────────────────┤
|
|
318
|
-
│ 💗 emotion ← user tone signals (frustration, etc.) │
|
|
319
|
-
├─────────────────────────────────────────────────────────────┤
|
|
320
|
-
│ 🛠 implementation ← how it was done (+ what failed) │
|
|
321
|
-
├─────────────────────────────────────────────────────────────┤
|
|
322
|
-
│ ⚠️ caveat ← "never do this again" · auto-protected │
|
|
323
|
-
├─────────────────────────────────────────────────────────────┤
|
|
324
|
-
│ 🌱 learning ← patterns distilled from cold memories │
|
|
325
|
-
└─────────────────────────────────────────────────────────────┘
|
|
326
|
-
│
|
|
327
|
-
▼
|
|
328
|
-
Ranked recall via relevance × heat × momentum × importance
|
|
329
|
-
Returns match_reasons explaining each hit
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
Every memory is tagged with **exactly one layer**. `caveat`-layer entries are protected from auto-forgetting. Cold low-importance memories can be consolidated into `learning` entries, but only if you opt in (`LINKSEE_AUTO_CONSOLIDATE=1` on the server — it deletes the originals; off by default since 0.17.1).
|
|
333
|
-
|
|
334
|
-
---
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
## Quick Start — One Command
|
|
338
|
-
|
|
339
|
-
```bash
|
|
340
|
-
npx -y linksee-memory setup
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
This sets up **Claude Code**:
|
|
344
|
-
1. Registers the MCP server (`claude mcp add -s user linksee -- npx -y linksee-memory`)
|
|
345
|
-
2. Installs the agent skill (teaches the agent when to recall/remember)
|
|
346
|
-
3. Configures auto-capture — a `Stop` hook, so every session is saved to your local memory
|
|
347
|
-
4. Wires the [re-injection guard](#reinjection-guard) for every repo (`--project-guard` for this repo only, `--no-guard` to skip)
|
|
348
|
-
|
|
349
|
-
**What is shared, and what is Claude Code only.** The memory itself (the MCP tools `remember` / `recall` / …) works from any MCP client — Claude Code, Cursor, Windsurf, OpenAI Codex, Gemini CLI — and they all use the same `~/.linksee-memory/memory.db`. Auto-capture and the guard are Claude Code hooks: other clients save and recall only when the agent calls the tools.
|
|
34
|
+
[](https://www.npmjs.com/package/linksee-memory)
|
|
35
|
+
[](./LICENSE)
|
|
36
|
+
[](https://registry.modelcontextprotocol.io/)
|
|
37
|
+
[](https://glama.ai/mcp/servers/michielinksee/linksee-memory)
|
|
350
38
|
|
|
351
|
-
|
|
39
|
+
Docs: [docs.linksee.app](https://docs.linksee.app) · Site: [linksee.app](https://linksee.app) (setup guides for non-developers) · Free, MIT, local only — there is no paid tier you need.
|
|
352
40
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
(Cursor, Windsurf and Gemini CLI: see [Other editors / CLIs](#other-editors--clis).)
|
|
41
|
+
<!-- releases: tag-driven, published from CI via npm trusted publishing (OIDC).
|
|
42
|
+
See .github/workflows/publish.yml — no token, no OTP, provenance attached automatically. -->
|
|
358
43
|
|
|
359
|
-
|
|
360
|
-
1. In Claude Code, say: *"Remember: in this repo we decided to use X, because Y."*
|
|
361
|
-
2. Open a **new** session and ask: *"What did we decide about X?"*
|
|
44
|
+
<a id="what-setup-writes"></a>
|
|
362
45
|
|
|
363
|
-
|
|
46
|
+
## What setup writes, and how to undo it
|
|
364
47
|
|
|
365
|
-
|
|
48
|
+
`setup` registers the MCP server (`claude mcp add -s user linksee -- npx -y linksee-memory`), installs the agent skill, adds a `Stop` hook that saves each session, and wires the [re-injection guard](docs/guard.md) for every repo (`--project-guard` for this repo only, `--no-guard` to skip). Running it again changes nothing that is already in place.
|
|
366
49
|
|
|
367
50
|
| File | What |
|
|
368
51
|
|---|---|
|
|
369
52
|
| `~/.claude.json` | the `linksee` MCP server (via `claude mcp add`) — undo with `claude mcp remove linksee` |
|
|
370
53
|
| `~/.claude/skills/linksee-memory/SKILL.md` | the agent skill |
|
|
371
54
|
| `~/.claude/settings.json` | the `Stop` hook (auto-capture) and the `SessionStart` / `PreToolUse` guard hooks. Merged into what is there — other hooks and settings are kept. If the file does not parse, setup leaves it untouched and says so. Before changing it, setup keeps the previous file as `settings.json.bak-<timestamp>`: to undo, copy that file back over `settings.json`. |
|
|
372
|
-
| `~/.linksee-memory/runtime/<version>/` | only when setup
|
|
55
|
+
| `~/.linksee-memory/runtime/<version>/` | only when setup ran from a temporary location (`npx`, `pnpm dlx`, `bunx`, or the system temp directory): setup runs `npm install --prefix ~/.linksee-memory/runtime/<version> --no-save --omit=dev linksee-memory@<version>` once (shown with its size; this downloads from the npm registry), because the hooks call `node` on it directly and those locations are temporary. Older versions are not removed automatically (about 35 MB each): setup prints the folder, and `npx -y linksee-memory runtime prune` lists them with what references each. With `--yes --scope-confirmed` it deletes only versions no settings file references; it cannot see other repos where you ran `setup --project` (pass their `.claude/settings.json` with `--settings`), and if a settings file cannot be read or parsed it deletes nothing. If the install fails, the hooks stay on the npx form. |
|
|
373
56
|
| `~/.linksee-memory/telemetry-consent` | your telemetry answer (`off` unless you said yes) |
|
|
374
57
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
### Manual setup (if you prefer step-by-step)
|
|
378
|
-
|
|
379
|
-
<details>
|
|
380
|
-
<summary>Click to expand manual installation</summary>
|
|
381
|
-
|
|
382
|
-
**Install & register:**
|
|
383
|
-
|
|
384
|
-
```bash
|
|
385
|
-
claude mcp add -s user linksee -- npx -y linksee-memory
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
Tools appear as `mcp__linksee__remember`, `mcp__linksee__recall`, `mcp__linksee__read_smart`.
|
|
389
|
-
|
|
390
|
-
**Install the skill (auto-invocation):**
|
|
391
|
-
|
|
392
|
-
```bash
|
|
393
|
-
npx -y linksee-memory install-skill
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
Copies `SKILL.md` to `~/.claude/skills/linksee-memory/`. Agent auto-fires on phrases like "前に…", "また同じエラー", "覚えておいて", new task starts, file edits, etc.
|
|
397
|
-
|
|
398
|
-
**Configure auto-capture (Stop hook):**
|
|
399
|
-
|
|
400
|
-
Add to `~/.claude/settings.json`:
|
|
401
|
-
|
|
402
|
-
```json
|
|
403
|
-
{
|
|
404
|
-
"hooks": {
|
|
405
|
-
"Stop": [
|
|
406
|
-
{
|
|
407
|
-
"matcher": "",
|
|
408
|
-
"hooks": [
|
|
409
|
-
{ "type": "command", "command": "npx -y linksee-memory sync" }
|
|
410
|
-
]
|
|
411
|
-
}
|
|
412
|
-
]
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
This `npx -y` form works anywhere, but every call starts npm and checks the registry: on the author's Windows machine one call took 7.4–8.6 s (3 runs, warm cache). `setup` writes a direct call instead — `"<path to node>" "<package>/dist/bin/sync-session.js" --linksee-managed` — which took 0.20–0.27 s on the same machine. Your numbers will differ; measure with your own hook log. Failures are silent. Logs at `~/.linksee-memory/hook.log`.
|
|
418
|
-
|
|
419
|
-
</details>
|
|
420
|
-
|
|
421
|
-
### Other editors / CLIs
|
|
422
|
-
|
|
423
|
-
Linksee Memory is a standard MCP server (stdio). Any tool that speaks MCP can connect:
|
|
424
|
-
|
|
425
|
-
<details>
|
|
426
|
-
<summary><strong>Cursor</strong></summary>
|
|
427
|
-
|
|
428
|
-
Add to `~/.cursor/mcp.json`:
|
|
429
|
-
|
|
430
|
-
```json
|
|
431
|
-
{
|
|
432
|
-
"mcpServers": {
|
|
433
|
-
"linksee": {
|
|
434
|
-
"command": "npx",
|
|
435
|
-
"args": ["-y", "linksee-memory"]
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
Restart Cursor. Memory tools appear in the agent panel.
|
|
442
|
-
|
|
443
|
-
</details>
|
|
444
|
-
|
|
445
|
-
<details>
|
|
446
|
-
<summary><strong>Windsurf</strong></summary>
|
|
447
|
-
|
|
448
|
-
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
449
|
-
|
|
450
|
-
```json
|
|
451
|
-
{
|
|
452
|
-
"mcpServers": {
|
|
453
|
-
"linksee": {
|
|
454
|
-
"command": "npx",
|
|
455
|
-
"args": ["-y", "linksee-memory"]
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
```
|
|
58
|
+
To remove everything: `claude mcp remove linksee`, delete the linksee hooks from `settings.json` (or copy the `.bak` back), then `rm -rf ~/.claude/skills/linksee-memory ~/.linksee-memory` — the last one deletes the memory stored in that folder. It does not reach copies you made yourself (for example to hand the memory over) or telemetry already sent if you opted in. Linksee itself never sends memory text anywhere. Step by step, with manual setup: [docs/install.md](docs/install.md).
|
|
460
59
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
<details>
|
|
464
|
-
<summary><strong>OpenAI Codex CLI</strong></summary>
|
|
465
|
-
|
|
466
|
-
```bash
|
|
467
|
-
codex mcp add linksee -- npx -y linksee-memory
|
|
468
|
-
```
|
|
60
|
+
## Other clients
|
|
469
61
|
|
|
470
|
-
|
|
62
|
+
Every client points at the same stdio command and the same `~/.linksee-memory/memory.db`. A decision made in Claude Code is recalled in Cursor.
|
|
471
63
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
<details>
|
|
481
|
-
<summary><strong>Gemini CLI</strong></summary>
|
|
482
|
-
|
|
483
|
-
Add to `~/.gemini/settings.json`:
|
|
484
|
-
|
|
485
|
-
```json
|
|
486
|
-
{
|
|
487
|
-
"mcpServers": {
|
|
488
|
-
"linksee": {
|
|
489
|
-
"command": "npx",
|
|
490
|
-
"args": ["-y", "linksee-memory"]
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
</details>
|
|
497
|
-
|
|
498
|
-
<details>
|
|
499
|
-
<summary><strong>Claude Desktop</strong></summary>
|
|
64
|
+
| Client | Where |
|
|
65
|
+
|---|---|
|
|
66
|
+
| OpenAI Codex | `codex mcp add linksee -- npx -y linksee-memory` |
|
|
67
|
+
| Cursor | `~/.cursor/mcp.json` |
|
|
68
|
+
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
|
|
69
|
+
| Gemini CLI | `~/.gemini/settings.json` |
|
|
70
|
+
| Claude Desktop | `claude_desktop_config.json` |
|
|
500
71
|
|
|
501
|
-
|
|
72
|
+
The JSON clients take the same block:
|
|
502
73
|
|
|
503
74
|
```json
|
|
504
|
-
{
|
|
505
|
-
"mcpServers": {
|
|
506
|
-
"linksee": {
|
|
507
|
-
"command": "npx",
|
|
508
|
-
"args": ["-y", "linksee-memory"]
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
75
|
+
{ "mcpServers": { "linksee": { "command": "npx", "args": ["-y", "linksee-memory"] } } }
|
|
512
76
|
```
|
|
513
77
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
</details>
|
|
517
|
-
|
|
518
|
-
All editors share the same `~/.linksee-memory/memory.db`. A decision made in Claude Code is recalled in Cursor. A caveat recorded in Windsurf prevents the same mistake in Codex.
|
|
519
|
-
|
|
520
|
-
### Database location
|
|
521
|
-
|
|
522
|
-
Default: `~/.linksee-memory/memory.db`. Override with `LINKSEE_MEMORY_DIR` env var.
|
|
523
|
-
|
|
524
|
-
### Uninstall
|
|
525
|
-
|
|
526
|
-
```bash
|
|
527
|
-
# 1. Remove the MCP server registration
|
|
528
|
-
claude mcp remove linksee
|
|
529
|
-
|
|
530
|
-
# 2. Remove the hooks from settings.json (edit the file, delete the linksee entries),
|
|
531
|
-
# or copy back the settings.json.bak-<timestamp> that setup left next to it:
|
|
532
|
-
# ~/.claude/settings.json → the Stop hook (…sync-session.js, or "npx -y linksee-memory sync")
|
|
533
|
-
# and the SessionStart/PreToolUse hooks (…guard-hook.js, or "npx -y linksee-memory guard")
|
|
534
|
-
# <project>/.claude/settings.json → the same guard hooks, if you used --project-guard
|
|
535
|
-
|
|
536
|
-
# 3. Remove the installed skill and all local memory (optional)
|
|
537
|
-
rm -rf ~/.claude/skills/linksee-memory
|
|
538
|
-
rm -rf ~/.linksee-memory # deletes all stored memory — nothing is kept anywhere else
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
Nothing ever leaves your machine, so step 3 fully erases everything Linksee stored.
|
|
542
|
-
|
|
543
|
-
## What's new in v0.17
|
|
544
|
-
|
|
545
|
-
| Feature | Detail |
|
|
546
|
-
|---|---|
|
|
547
|
-
| **`share_draft` (optional)** | When you ask to share how a SaaS / MCP / API connection got stuck and what fixed it, the agent fills fixed fields and gets back a link to a reviewed draft on KanseiLINK. **Linksee sends nothing** — you read the draft in your browser and only your click sends it. Anything that looks like a key, token, e-mail, tenant URL, IP or local path stops the link. See [Share a fix with other agents](#share-a-fix-with-other-agents-optional). |
|
|
548
|
-
| **MCP SDK 1.32.2** | `@modelcontextprotocol/sdk` raised to `^1.32.2`; `pnpm audit` 46 → 0. |
|
|
549
|
-
|
|
550
|
-
## What's new in v0.9
|
|
551
|
-
|
|
552
|
-
| Feature | Detail |
|
|
553
|
-
|---|---|
|
|
554
|
-
| **Re-injection guard** | The pre-action half of drift detection. A Claude Code `PreToolUse` hook re-surfaces (or, on a `hard` contradiction, blocks) an accepted decision *before* the agent runs `Edit`/`Write`/`Bash`; a `SessionStart` boot digest replays your locked decisions into each fresh session. Fail-open by design. See [Re-injection Guard](#reinjection-guard). |
|
|
555
|
-
| **Shippable hook wiring** | `linksee-memory-setup` now offers to merge the guard hooks into your project's `.claude/settings.json` (pointing at the published `linksee-memory-guard` bin), and the block is documented for copy-paste. Previously the wiring lived only in a gitignored dogfood config. |
|
|
556
|
-
|
|
557
|
-
## What's new in v0.8
|
|
78
|
+
Full configs, including Codex's `config.toml`: [docs/install.md](docs/install.md#other-editors--clis).
|
|
558
79
|
|
|
559
|
-
|
|
560
|
-
|---|---|
|
|
561
|
-
| **4 drift detection tools** | `drift_status`, `check_decision`, `declare_anchor`, `resolve_drift` — agents can now query and act on intent ↔ reality divergence. The biggest gap in agent memory (decisions are forgotten across sessions) is now closed. |
|
|
562
|
-
| **Truth engine** | State derivation logic (drift/review/held/aligned) now lives in the MCP engine, not just the dashboard. Any MCP client can query drift status. |
|
|
563
|
-
| **4-species taxonomy** | Anchors classified as hypothesis/constraint/commitment/source_of_truth with species-appropriate display formats. |
|
|
564
|
-
| **Resolution priority** | When multiple resolutions exist for an anchor, the most recent one wins (prevents stale acknowledge from shadowing a newer fix). |
|
|
80
|
+
## Everyday use
|
|
565
81
|
|
|
566
|
-
|
|
567
|
-
<summary>What's new in v0.7</summary>
|
|
568
|
-
|
|
569
|
-
| Feature | Detail |
|
|
82
|
+
| Say this | What happens |
|
|
570
83
|
|---|---|
|
|
571
|
-
| **
|
|
572
|
-
| **
|
|
573
|
-
| **
|
|
574
|
-
| **"Use Linksee Memory" trigger** | Add "Use Linksee Memory" to any prompt to force memory recall — same adoption pattern as Context7. |
|
|
575
|
-
| **Claude Code Plugin** | `claude plugin add -- linksee-memory` — ships MCP server + auto-invocation skill in one install. |
|
|
576
|
-
|
|
577
|
-
</details>
|
|
84
|
+
| **"use linksee"** | Recalls relevant memories before acting |
|
|
85
|
+
| **"linksee this"** | Saves the decision or lesson now |
|
|
86
|
+
| **"what's drifting?"** | Checks reality against the decisions you recorded |
|
|
578
87
|
|
|
579
|
-
|
|
580
|
-
<summary>What's new in v0.4</summary>
|
|
88
|
+
Adding **"Use Linksee Memory"** to your system prompt or `CLAUDE.md` prompts the agent to call `recall` more often; whether it does is still up to the agent.
|
|
581
89
|
|
|
582
|
-
|
|
583
|
-
|---|---|
|
|
584
|
-
| **One-command setup** | `npx -y linksee-memory setup` — registers MCP server, installs skill, configures auto-capture hook. One command instead of three. |
|
|
585
|
-
| **Structured memory v2** | 3-axis classification (altitude × type × state) for every memory. Auto-extraction from sessions produces machine-scannable JSON, not raw chat dumps. |
|
|
586
|
-
| **Precision recall guide** | SKILL.md now teaches agents HOW to write effective queries, WHEN to recall vs skip, and WHEN to proactively surface caveats before risky actions. |
|
|
587
|
-
| **Five MCP Blocks** | Tools + Resources + Prompts + Sampling + Roots + Elicitation. Most MCP servers expose only Tools; linksee-memory implements all five primitives. |
|
|
90
|
+
What each part does, and where:
|
|
588
91
|
|
|
589
|
-
|
|
92
|
+
- **Shared (every client):** `remember` saves to the one SQLite file; `recall` searches it when the agent calls it.
|
|
93
|
+
- **Re-injected (Claude Code only, hooks):** `remember({ content, anchor: {} })` also records the decision as an anchor. At session start the guard hook adds a short digest of recorded decisions (up to 8). Before an `Edit` / `Write` / `Bash`, a decision comes back only if it matches: with `affects` globs, the edited path must match (a `Bash` command that names no file can still match on a `violation_signal`); without `affects`, a `detect_terms` or `violation_signal` hit is needed. An empty `anchor: {}` has none of these, so it appears only in the session-start digest, never before an edit.
|
|
94
|
+
- **Contradiction warned or blocked (Claude Code only):** the guard can only tell that an edit contradicts a decision if you give it the strings that mean "contradiction": `anchor: { violation_signal: ["pgvector"] }`. An empty `anchor: {}` is stored as a constraint and is re-injected, never matched as a contradiction. A match warns; after `resolve_drift(action: "harden")` it blocks. The guard fails open: its own errors never block anything. Details: [docs/guard.md](docs/guard.md).
|
|
590
95
|
|
|
591
|
-
##
|
|
96
|
+
## Tools: seven, six for memory and drift and one you ask for
|
|
592
97
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
98
|
+
Three for memory, three for drift, and `share_draft`, which runs only when the user asks.
|
|
99
|
+
Earlier versions exposed more, and how agents used them varied from model to model; six is what
|
|
100
|
+
an agent can hold without a manual.
|
|
596
101
|
|
|
597
102
|
| Tool | What it does |
|
|
598
103
|
|---|---|
|
|
599
104
|
| `recall` | **Start here.** No arguments → the **session brief**: what needs attention, where you are on the Map, open loops, top entities. `query` → search; `path` → a file's edit history with the user intent behind each edit; `where: "<topic>"` → your position on the Current Truth Map + blast radius; `dream: true` → the triage session (North Star, orphaned proposals, distill queue, friction). |
|
|
600
|
-
| `remember` | **Save / update / delete.** `content` is the only required field — entity and layer default to the project you're in. Add `anchor: {}` to record a decision
|
|
105
|
+
| `remember` | **Save / update / delete.** `content` is the only required field — entity and layer default to the project you're in. Add `anchor: {}` to also record it as a decision (in Claude Code, re-injected on session start and before a matching Edit/Write/Bash); add `violation_signal` to it so a contradicting edit can be detected. `supersedes: <id>` replaces an older memory of the same entity (recall hides the old one). |
|
|
601
106
|
| `read_smart` | **Token-saving file reader** with AST diff caching. Re-read unchanged = ~50 tokens; modified = changed chunks only. |
|
|
602
107
|
| `drift_status` | **"What's drifting right now?"** The truth map: 🔴 drift / 🟡 review / ⚪ held / 🔵 verified / ⚫ unverified, with the evidence for each. `anchor_id` → deep-dive into one decision. |
|
|
603
108
|
| `declare_anchor` | **Record a normative claim** — `decision` / `prohibition` / `constraint` the detector checks against reality, or `proposal`: an option you presented that the user never addressed, parked as a review item. |
|
|
@@ -612,87 +117,36 @@ One more tool sits outside the memory/drift surface and does nothing unless the
|
|
|
612
117
|
`share_draft` — builds a link to a reviewed draft of a fix for other agents. See
|
|
613
118
|
[Share a fix with other agents](#share-a-fix-with-other-agents-optional).
|
|
614
119
|
|
|
615
|
-
|
|
120
|
+
**CLI**
|
|
616
121
|
|
|
617
122
|
| Command | Purpose |
|
|
618
123
|
|---|---|
|
|
619
124
|
| `npx -y linksee-memory setup` | One-command setup: MCP server + skill + Stop hook + the re-injection guard for every repo (`--project-guard` for this repo only, `--no-guard` to skip). Idempotent — skips what's already done. |
|
|
620
125
|
| `npx linksee-memory` | MCP server (stdio) |
|
|
621
126
|
| `npx -y linksee-memory sync` | Claude Code Stop-hook entry point |
|
|
622
|
-
| `npx -y linksee-memory guard` | Re-injection guard hook: `PreToolUse` gate (`Edit`/`Write`/`Bash`) + `SessionStart` boot digest. Wired by `setup` for every repo (see [Re-injection Guard](
|
|
127
|
+
| `npx -y linksee-memory guard` | Re-injection guard hook: `PreToolUse` gate (`Edit`/`Write`/`Bash`) + `SessionStart` boot digest. Wired by `setup` for every repo (see [Re-injection Guard](docs/guard.md)); fail-open. |
|
|
623
128
|
| `npx -y linksee-memory import` | Batch-import Claude Code session JSONL history |
|
|
624
129
|
| `npx -y linksee-memory install-skill` | Install the Claude Code Skill that teaches the agent when to call recall/remember/read_smart |
|
|
625
130
|
| `npx -y linksee-memory stats` | Summary of the local DB (entity count / layer breakdown / top entities / top edited files). Add `--json` for machine-readable output. |
|
|
626
131
|
| `npx -y linksee-memory share-draft --help` | Print a link to a reviewed draft of a fix (same checks as the `share_draft` tool). Sends nothing. |
|
|
627
132
|
|
|
628
|
-
##
|
|
629
|
-
|
|
630
|
-
Each entity (person / company / project / file / concept) can have memories across six layers. Since v0.4, each memory uses the **3-axis structured format** (altitude × type × state):
|
|
631
|
-
|
|
632
|
-
```json
|
|
633
|
-
{
|
|
634
|
-
"title": "freee OAuth token expires in 24h",
|
|
635
|
-
"altitude": "implementation",
|
|
636
|
-
"type": "outcome",
|
|
637
|
-
"state": "done",
|
|
638
|
-
"what": "freee OAuth token expires in 24 hours. Must refresh proactively.",
|
|
639
|
-
"why": "freee uses short-lived tokens unlike most SaaS (usually 30-90 day expiry)",
|
|
640
|
-
"affects": ["src/integrations/freee/auth.ts"],
|
|
641
|
-
"next_action": null
|
|
642
|
-
}
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
- `caveat` memories are auto-protected from forgetting (pain lessons, never lost).
|
|
646
|
-
- `goal` memories bypass decay while the goal is active.
|
|
647
|
-
- `state` tracks lifecycle: `open` → `decided` → `in_progress` → `done` / `stalled` / `superseded`.
|
|
648
|
-
|
|
649
|
-
## Architecture
|
|
650
|
-
|
|
651
|
-
A single SQLite file (`better-sqlite3` + FTS5 trigram tokenizer for JP/EN) contains five layers:
|
|
133
|
+
## Drift and the product map
|
|
652
134
|
|
|
653
|
-
|
|
654
|
-
- **Layer 2** — `edges` (associations, graph adjacency)
|
|
655
|
-
- **Layer 3** — `memories` (6-layer structured meanings per entity)
|
|
656
|
-
- **Layer 4** — `events` (time-series log for heat / momentum computation)
|
|
657
|
-
- **Layer 5** — `file_snapshots` + `session_file_edits` (diff cache + conversation↔file linkage)
|
|
135
|
+
Drift is a recorded decision that the code has quietly left — last week you chose FTS5 over vector search, this week a new session installs `pgvector`. `drift_status` lists each decision as 🔴 drift, 🟡 review, ⚪ held, 🔵 verified or ⚫ unverified, with evidence. A change you recorded as `fix` or `supersede` stays quiet; only unaccounted gaps are flagged.
|
|
658
136
|
|
|
659
|
-
|
|
137
|
+
`linksee-memory map` lifts this to the whole product: a `map.yaml` of how the pieces fit, checked against the code with file:line evidence.
|
|
660
138
|
|
|
661
|
-
|
|
139
|
+

|
|
662
140
|
|
|
663
|
-
|
|
664
|
-
- **Single file** — `memory.db` is one portable artifact. Backup = file copy.
|
|
665
|
-
- **MCP stdio** — works with every agent that speaks MCP, no plugins per host.
|
|
666
|
-
- **Reuses proven schemas** — `heat_score` / `momentum_score` ported from a production sales-intelligence codebase. Rule-based, no LLM dependency in the hot path.
|
|
141
|
+
In the demo the README promises `--export` and the code does not implement it; the map flags it and lists what else a change would touch.
|
|
667
142
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
-
|
|
671
|
-
-
|
|
672
|
-
|
|
673
|
-
- ✅ Five MCP Blocks (Tools + Resources + Prompts + Sampling + Roots + Elicitation)
|
|
674
|
-
- ✅ Stop-hook auto-capture for Claude Code
|
|
675
|
-
- ✅ JP/EN trigram FTS5
|
|
676
|
-
- ✅ One-command setup (`npx -y linksee-memory setup`)
|
|
677
|
-
- ✅ Structured memory v2 (3-axis classification: altitude × type × state)
|
|
678
|
-
- ✅ Cross-LLM: Claude Code, Cursor, Windsurf, OpenAI Codex, Gemini CLI
|
|
679
|
-
- ✅ Landing page ([linksee.app](https://linksee.app))
|
|
680
|
-
- ✅ Drift detection engine + 4 MCP drift tools — v0.8.0
|
|
681
|
-
- ✅ 4-species truth map (hypothesis/constraint/commitment/source_of_truth) — v0.8.0
|
|
682
|
-
- ✅ Dashboard with Decision Register visualization
|
|
683
|
-
- ✅ `share_draft`: share a fix as a reviewed link, never a send — v0.17.0
|
|
684
|
-
- 🔮 Obsidian plugin (read truth map in your vault)
|
|
685
|
-
- 🔮 Vector search via `sqlite-vec` (already in deps, embedding backend pending)
|
|
686
|
-
- 🔮 Cross-device cloud sync (Pro tier)
|
|
687
|
-
|
|
688
|
-
## Comparison with Claude Code auto-memory
|
|
689
|
-
|
|
690
|
-
Claude Code ships a built-in memory feature at `~/.claude/projects/<path>/memory/*.md` — flat markdown notes for user preferences. linksee-memory **complements** it:
|
|
691
|
-
|
|
692
|
-
- auto-memory = your scrapbook of "remember I prefer X"
|
|
693
|
-
- linksee-memory = structured cross-agent brain with file diff cache and per-edit WHY
|
|
143
|
+
```bash
|
|
144
|
+
npx -y linksee-memory map where README.md # which map node this file belongs to, and what it touches
|
|
145
|
+
npx -y linksee-memory map explain readme # why the node is in its state, with evidence
|
|
146
|
+
npx -y linksee-memory map affects readme # what else a change here must move
|
|
147
|
+
```
|
|
694
148
|
|
|
695
|
-
|
|
149
|
+
States, resolutions, the four species and the full map CLI: [docs/drift-and-map.md](docs/drift-and-map.md).
|
|
696
150
|
|
|
697
151
|
## Share a fix with other agents (optional)
|
|
698
152
|
|
|
@@ -725,234 +179,84 @@ SaaS・MCP・API の接続で詰まって直った(または直らなかった
|
|
|
725
179
|
|
|
726
180
|
</details>
|
|
727
181
|
|
|
728
|
-
## Security
|
|
182
|
+
## Security and privacy
|
|
729
183
|
|
|
730
184
|
linksee-memory runs locally and is built to read — and send — as little as possible.
|
|
731
185
|
|
|
732
186
|
- **Local-first.** Memory is one SQLite file at `~/.linksee-memory/memory.db`. No account, no cloud, no API key.
|
|
733
|
-
- **Telemetry is opt-in and OFF by default.** `setup` asks once; nothing is sent unless you agree there (or set `LINKSEE_TELEMETRY=basic`). Even then it never sends your source code, file contents, prompts, conversation, entity/project names, or the memory DB — only anonymous counters ([details](
|
|
187
|
+
- **Telemetry is opt-in and OFF by default.** `setup` asks once; nothing is sent unless you agree there (or set `LINKSEE_TELEMETRY=basic`). Even then it never sends your source code, file contents, prompts, conversation, entity/project names, or the memory DB — only anonymous counters ([details](docs/telemetry.md)).
|
|
734
188
|
- **No automatic repo crawling.** linksee reads: memory you explicitly save, your `map.yaml`, the specific files a map reality-check points at, the local SQLite DB, and — when the Stop hook fires — your Claude Code session transcript (locally, to capture what happened). It does **not** crawl your repo, read `.env`/secrets/`node_modules`, or touch your home directory on its own.
|
|
735
189
|
- **`share_draft` makes a link only; Linksee itself never sends it.** The user opens it and decides ([details](#share-a-fix-with-other-agents-optional)).
|
|
736
190
|
- **Clean MCP transport.** The server writes only JSON-RPC to stdout; all logs go to stderr.
|
|
737
|
-
- **Hooks are documented and removable.** `setup` adds a Stop hook (session capture) and
|
|
191
|
+
- **Hooks are documented and removable.** `setup` adds a Stop hook (session capture) and the guard hooks (skip them with `--no-guard`). They send nothing unless you opted in to telemetry (then the Stop hook posts one set of counters per session). Hooks written in the `npx -y` form — the fallback when setup cannot write a direct `node` call — start npm, which checks the registry. They are time-bounded, fail-open (a hook error never breaks your session), and are listed under [Uninstall](docs/install.md#uninstall).
|
|
738
192
|
- **No shell-injection surface.** Subcommands run via `spawn` with array args and `shell: false`, from a fixed allowlist; `map.yaml` is parsed with the safe `yaml` parser (no arbitrary tag execution).
|
|
739
193
|
- **Supply chain.** MIT, published from a single owner. `npx -y linksee-memory` runs the published package — pin a version in CI if you need reproducibility.
|
|
740
194
|
|
|
741
|
-
Found a security issue? See [SECURITY.md](SECURITY.md).
|
|
742
|
-
|
|
743
|
-
## Telemetry (opt-in, off by default)
|
|
744
|
-
|
|
745
|
-
linksee-memory ships with **opt-in** anonymous telemetry that helps us understand which MCP servers and workflows actually work in the wild. **Nothing is sent unless you explicitly enable it.** No conversation content, no file content, no entity names, no project paths — ever.
|
|
746
|
-
|
|
747
|
-
### Enable
|
|
748
|
-
|
|
749
|
-
```bash
|
|
750
|
-
export LINKSEE_TELEMETRY=basic # opt in
|
|
751
|
-
export LINKSEE_TELEMETRY=off # opt out (or just unset the variable)
|
|
752
|
-
# `linksee-memory setup` also asks once and records your choice in
|
|
753
|
-
# ~/.linksee-memory/telemetry-consent (delete that file to be asked again).
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
### Exactly what gets sent (Level 1 contract)
|
|
757
|
-
|
|
758
|
-
After each Claude Code session ends, the Stop hook sends one POST to `https://linksee-site.vercel.app/api/telemetry/linksee` containing only these fields:
|
|
759
|
-
|
|
760
|
-
| Field | Example | What it is |
|
|
761
|
-
|---|---|---|
|
|
762
|
-
| `anon_id` | `d7924ced-3879-…` | Random UUID generated locally on first opt-in. Stored at `~/.linksee-memory/telemetry-id` — delete the file to reset. |
|
|
763
|
-
| `linksee_version` | `0.0.3` | Package version |
|
|
764
|
-
| `session_turn_count` | `120` | How many turns the session had |
|
|
765
|
-
| `session_duration_sec` | `3600` | How long the session lasted |
|
|
766
|
-
| `file_ops_edit/write/read` | `12, 2, 40` | Counts only |
|
|
767
|
-
| `mcp_servers` | `["kansei-link","freee","slack"]` | Names of MCP servers configured (from `~/.claude.json`). Names only — never command paths. |
|
|
768
|
-
| `file_extensions` | `{".ts":60,".md":30}` | Percent distribution of file extensions touched |
|
|
769
|
-
| `read_smart_*`, `recall_*` | counts | Tool usage counters |
|
|
770
|
-
|
|
771
|
-
**What is NEVER sent**:
|
|
772
|
-
- ❌ Conversation messages (user or assistant)
|
|
773
|
-
- ❌ File contents
|
|
774
|
-
- ❌ Entity names, project names, file paths, URLs
|
|
775
|
-
- ❌ Memory-layer text (goal / context / emotion / impl / caveat / learning)
|
|
776
|
-
- ❌ Authentication tokens, API keys, secrets
|
|
777
|
-
- ❌ Your IP address (only a one-way hash for abuse detection)
|
|
778
|
-
|
|
779
|
-
### Why we ask
|
|
780
|
-
|
|
781
|
-
Aggregated MCP-usage data helps the [KanseiLink](https://kansei-link.com) project rank which agent integrations actually work for real developers. If you're happy to contribute, `LINKSEE_TELEMETRY=basic` takes 1 second to set and helps the entire MCP ecosystem improve.
|
|
782
|
-
|
|
783
|
-
The full payload schema and validation logic is open-source — read `src/lib/telemetry.ts` if you want to verify exactly what leaves your machine.
|
|
784
|
-
|
|
785
|
-
## Pricing
|
|
786
|
-
|
|
787
|
-
**Free forever.**
|
|
195
|
+
Found a security issue? See [SECURITY.md](./SECURITY.md).
|
|
788
196
|
|
|
789
|
-
|
|
197
|
+
Every telemetry field, and what is never sent: [docs/telemetry.md](docs/telemetry.md).
|
|
790
198
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
## Troubleshooting
|
|
794
|
-
|
|
795
|
-
<details>
|
|
796
|
-
<summary><b>The skill isn't firing — Claude Code doesn't call <code>recall</code> when I ask about past work.</b></summary>
|
|
797
|
-
|
|
798
|
-
1. Verify the skill was installed:
|
|
799
|
-
```bash
|
|
800
|
-
ls ~/.claude/skills/linksee-memory/SKILL.md
|
|
801
|
-
```
|
|
802
|
-
If absent, run `npx -y linksee-memory install-skill`.
|
|
803
|
-
2. Restart Claude Code. Skills are indexed on session start.
|
|
804
|
-
3. Check that the MCP is registered under the name `linksee` (the skill expects `mcp__linksee__*` tool names):
|
|
805
|
-
```bash
|
|
806
|
-
claude mcp list | grep linksee
|
|
807
|
-
```
|
|
808
|
-
If it's registered as something else, either re-register or edit `~/.claude/skills/linksee-memory/SKILL.md` to match.
|
|
809
|
-
</details>
|
|
810
|
-
|
|
811
|
-
<details>
|
|
812
|
-
<summary><b>Stop hook isn't recording my sessions.</b></summary>
|
|
813
|
-
|
|
814
|
-
1. Check the hook log: `cat ~/.linksee-memory/hook.log`
|
|
815
|
-
2. Run a manual test:
|
|
816
|
-
```bash
|
|
817
|
-
echo '{"session_id":"test","transcript_path":"/path/to/some.jsonl"}' | npx -y linksee-memory sync
|
|
818
|
-
```
|
|
819
|
-
3. Make sure the `Stop` hook in `~/.claude/settings.json` points to `npx -y linksee-memory sync` (not the old `-import`).
|
|
820
|
-
</details>
|
|
821
|
-
|
|
822
|
-
<details>
|
|
823
|
-
<summary><b>Upgrading from v0.0.5 or earlier — my recalls are mostly tagged "Card_Navi" or my project-dir name.</b></summary>
|
|
824
|
-
|
|
825
|
-
v0.0.6+ fixed the entity detection bug that collapsed all memories into the session's starting cwd. To re-index existing history with correct project attribution, run:
|
|
826
|
-
|
|
827
|
-
```bash
|
|
828
|
-
npx -y linksee-memory import --all
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
The importer is idempotent (wipes existing session data before re-inserting). Typical runtime: a few minutes for hundreds of sessions. Expect a dramatic improvement in `recall` precision afterward.
|
|
832
|
-
</details>
|
|
833
|
-
|
|
834
|
-
<details>
|
|
835
|
-
<summary><b><code>recall</code> returns too much — the context window fills up fast.</b></summary>
|
|
836
|
-
|
|
837
|
-
Reduce `max_tokens`:
|
|
838
|
-
```
|
|
839
|
-
recall({ query: "...", max_tokens: 800 }) // default is 2000
|
|
840
|
-
```
|
|
841
|
-
Or narrow with `entity_name` and `layer`:
|
|
842
|
-
```
|
|
843
|
-
recall({ query: "...", entity_name: "my-project", layer: "caveat" })
|
|
844
|
-
```
|
|
845
|
-
</details>
|
|
846
|
-
|
|
847
|
-
<details>
|
|
848
|
-
<summary><b>How do I reset / delete all memory?</b></summary>
|
|
849
|
-
|
|
850
|
-
```bash
|
|
851
|
-
rm -rf ~/.linksee-memory # nuke everything; next run creates a fresh DB
|
|
852
|
-
```
|
|
853
|
-
|
|
854
|
-
Or delete individual memories via `remember({ forget: true, memory_id: <id> })`.
|
|
855
|
-
</details>
|
|
856
|
-
|
|
857
|
-
<details>
|
|
858
|
-
<summary><b>DB is getting large (>100 MB). How do I trim it?</b></summary>
|
|
859
|
-
|
|
860
|
-
Since 0.17.1 nothing is consolidated automatically: consolidation deletes the original rows (keeping a short summary), so it runs only if you start the server with `LINKSEE_AUTO_CONSOLIDATE=1` (then at most weekly, 7-day threshold). When enabled it clusters old cold memories into compressed learning-layer summaries and deletes the originals; caveat and active-goal layers are always preserved. Back up `~/.linksee-memory/` before turning it on. There is no `consolidate` tool to call.
|
|
861
|
-
</details>
|
|
862
|
-
|
|
863
|
-
## FAQ
|
|
864
|
-
|
|
865
|
-
<details>
|
|
866
|
-
<summary><strong>What is drift detection and why do I need it?</strong></summary>
|
|
867
|
-
|
|
868
|
-
Drift = when your code reality silently diverges from what you decided. Example: Last week you decided "FTS5, not vector search" but this week a new agent session installs pgvector without knowing the history.
|
|
869
|
-
|
|
870
|
-
Linksee Memory tracks this by letting you declare decisions as "anchors" and then automatically checking committed code against them. The make-or-break rule: **intentional evolution (recorded as fix/supersede) stays quiet, while unaccounted gaps get flagged.** It's like Datadog but for product decisions instead of server metrics.
|
|
871
|
-
|
|
872
|
-
You don't need to use drift detection to benefit from linksee-memory — the 3 memory tools (remember/recall/read_smart) work independently. Drift tools are an additional layer for teams and solo devs managing multiple projects.
|
|
873
|
-
</details>
|
|
874
|
-
|
|
875
|
-
<details>
|
|
876
|
-
<summary><strong>How is this different from Mem0 / Letta / Zep?</strong></summary>
|
|
877
|
-
|
|
878
|
-
Three axes:
|
|
879
|
-
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.
|
|
880
|
-
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.
|
|
881
|
-
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.
|
|
882
|
-
</details>
|
|
883
|
-
|
|
884
|
-
<details>
|
|
885
|
-
<summary><strong>Why not just use Claude's built-in auto-memory?</strong></summary>
|
|
886
|
-
|
|
887
|
-
Claude Code's auto-memory is Claude-only (doesn't help if you switch to Cursor, OpenAI Codex, or Gemini CLI) and stores flat markdown with no structure. linksee-memory is the same local-first principle but:
|
|
888
|
-
- Works across Claude Code, Cursor, OpenAI Codex, Gemini CLI (shared SQLite)
|
|
889
|
-
- Structured 6-layer format makes recall explainable
|
|
890
|
-
- Consolidation of cold memories is opt-in (`LINKSEE_AUTO_CONSOLIDATE=1`, deletes originals); caveats are permanently protected
|
|
891
|
-
</details>
|
|
892
|
-
|
|
893
|
-
<details>
|
|
894
|
-
<summary><strong>Is 86% token savings real? Where does it come from?</strong></summary>
|
|
895
|
-
|
|
896
|
-
Yes — see `tools/bench-read-smart.ts` in the repo. The `read_smart` tool:
|
|
897
|
-
1. Hashes file content on first read, returns full content + chunk metadata (AST/heading/indent boundaries).
|
|
898
|
-
2. On re-read with unchanged mtime+sha256, returns `~50 tokens` of "unchanged" confirmation instead of re-sending the file.
|
|
899
|
-
3. On real edits, returns only the changed chunks as full content + unchanged chunks as metadata-only references.
|
|
900
|
-
|
|
901
|
-
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%.
|
|
902
|
-
</details>
|
|
903
|
-
|
|
904
|
-
<details>
|
|
905
|
-
<summary><strong>Does "local-first" mean no way to sync across my machines?</strong></summary>
|
|
906
|
-
|
|
907
|
-
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.)
|
|
908
|
-
</details>
|
|
909
|
-
|
|
910
|
-
<details>
|
|
911
|
-
<summary><strong>What happens when the DB gets huge?</strong></summary>
|
|
199
|
+
## Questions this answers
|
|
912
200
|
|
|
913
|
-
|
|
914
|
-
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.
|
|
915
|
-
2. **Consolidation (opt-in)**: off by default since 0.17.1. With `LINKSEE_AUTO_CONSOLIDATE=1` on the server it runs at start-up at most weekly (7-day threshold), compressing clusters of cold low-importance memories by entity into a single `learning`-layer summary and deleting the originals.
|
|
201
|
+
These are the questions people actually type — measured, verbatim (2026-09-04). If yours is here, this is the answer.
|
|
916
202
|
|
|
917
|
-
|
|
918
|
-
|
|
203
|
+
**Claude Code forgets everything when I start a new session. How do I make it remember decisions across sessions?**
|
|
204
|
+
Run `npx -y linksee-memory setup`. In Claude Code, each new session starts with a short digest of your recorded decisions and open items, injected by the SessionStart hook; the agent can call `recall()` (no arguments) for the full brief — what needs attention, where you are, what's unresolved. Decisions whose paths or terms an edit touches come back before that edit.
|
|
919
205
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
Yes — any MCP-compatible client works:
|
|
924
|
-
- **Claude Code**: `claude mcp add -s user linksee -- npx -y linksee-memory`
|
|
925
|
-
- **Claude Desktop**: add to `claude_desktop_config.json` (see [onboarding on the LP](https://linksee.app))
|
|
926
|
-
- **Cursor**: add to MCP settings in Cursor → Settings → Features → Model Context Protocol
|
|
927
|
-
- **OpenAI Codex**: `codex mcp add linksee -- npx -y linksee-memory` (or `~/.codex/config.toml` with `[mcp_servers.linksee]` block)
|
|
928
|
-
- **Gemini CLI**: add to `~/.gemini/settings.json` mcpServers section
|
|
929
|
-
- **ChatGPT (web/mobile app)**: stdio MCP not supported by the consumer app — requires Remote MCP server over HTTPS (not yet available).
|
|
930
|
-
- **Custom agent**: the MCP stdio protocol is documented at modelcontextprotocol.io
|
|
931
|
-
</details>
|
|
206
|
+
**Claude Codeがセッションをまたぐと過去の経緯を忘れてしまいます。記憶を持たせる方法を教えてください。**
|
|
207
|
+
`npx -y linksee-memory setup` の一回で入ります。Claude Code では、新しいセッションの最初に SessionStart フックが記録済みの決定と未解決の要約を差し込みます。全体の brief(注意すべきこと・いまどこか・未解決)は、エージェントが `recall()` を引数なしで呼んだときに出ます。編集が決定の対象のパスや語に触れると、その編集の直前にも出ます。
|
|
932
208
|
|
|
933
|
-
|
|
934
|
-
|
|
209
|
+
**What is the best MCP server for persistent memory across AI coding agents?**
|
|
210
|
+
Honest answer: if "remember across sessions" is all you need, a `CLAUDE.md` is enough — we measured it. Linksee is for the three moments it isn't: right before a mistake, when you change your mind, and when you run many projects and need to see which one drifted.
|
|
935
211
|
|
|
936
|
-
**
|
|
937
|
-
|
|
212
|
+
**AIコーディングエージェント用の記憶MCPサーバーでおすすめはありますか?**
|
|
213
|
+
正直に言うと、「セッションを跨いで覚える」だけなら `CLAUDE.md` で足ります(実測しました)。Linksee が要るのは、間違いかけたとき・方針を変えたとき・並行案件のどれが外れたかを知りたいとき、の3場面です。
|
|
938
214
|
|
|
939
|
-
|
|
940
|
-
|
|
215
|
+
**I want one shared memory between Claude Code, Cursor, and OpenAI Codex. What tools exist for that?**
|
|
216
|
+
One SQLite file. Claude Code, Cursor, Windsurf, OpenAI Codex and Gemini CLI all read and write the same memory — a decision recorded in one can be recalled in the others. Only Claude Code brings it back automatically before an edit (hooks).
|
|
941
217
|
|
|
942
|
-
|
|
943
|
-
|
|
218
|
+
**Claude CodeとCursorとCodexで同じ記憶を共有したいのですが、どうすればいいですか?**
|
|
219
|
+
SQLite ファイル1つを全員で読み書きします。Claude Code / Cursor / Windsurf / Codex / Gemini CLI のどこで記録した決定も、他のクライアントから `recall` で引けます。行動の直前に自動で出るのは Claude Code だけです(フックのため)。
|
|
944
220
|
|
|
945
|
-
|
|
221
|
+
**My AI agent keeps re-implementing things we already decided against. How can I detect that a codebase has drifted from past decisions?**
|
|
222
|
+
Declare the decision (`remember({ content, anchor: { violation_signal: [...] } })`). In Claude Code the guard then warns — or blocks, if you hardened it — the moment an edit contradicts it, and `drift_status` shows every decision that reality has quietly left.
|
|
946
223
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
- **Security concerns**: see [SECURITY.md](./SECURITY.md) if present, or file a private advisory on GitHub
|
|
950
|
-
- **Company**: Synapse Arrows PTE. LTD. (Singapore)
|
|
224
|
+
**過去に決めた設計方針とコードがずれていないかを検出できるツールはありますか?**
|
|
225
|
+
決定を「反したと分かる語」つきで宣言しておくと(`remember({ content, anchor: { violation_signal: [...] } })`)、Claude Code ではそれに反する編集の直前に警告(hardened なら拒否)が出ます。`drift_status` は「宣言と現実がずれた決定」を証拠つきで一覧します。
|
|
951
226
|
|
|
952
|
-
|
|
227
|
+
**Is there a local-first, self-hosted alternative to Mem0 for agent memory?**
|
|
228
|
+
Yes. No account, no API key, no cloud — one local file, MIT licensed. `npx -y linksee-memory setup` and it's on.
|
|
953
229
|
|
|
954
|
-
|
|
230
|
+
**Mem0 vs Zep vs Letta for a coding agent's long-term memory — which should I pick?**
|
|
231
|
+
We installed them and ran one scenario across all of them. Storing and recalling a decision: everyone passes. The difference appears *before a mistake* and *when you change your mind* — Linksee is built for those two moments; the others leave them to you.
|
|
955
232
|
|
|
956
|
-
|
|
233
|
+
**How do I stop Claude Code from repeating the same mistake it made last week?**
|
|
234
|
+
Record it as a caveat (`remember({ content, layer: 'caveat' })`). Caveats are protected from forgetting and come back when `recall` touches the same ground again. To have Claude Code stop the repeat before it lands, record it as an anchor with a `violation_signal`, then harden it (`resolve_drift(action: "harden")`); without hardening, a match only warns.
|
|
957
235
|
|
|
958
|
-
|
|
236
|
+
**開発の意思決定履歴をMCPサーバーで残しておく定番のやり方はありますか?**
|
|
237
|
+
`remember({ content, anchor: {} })` の1回で、記録と決定の登録が同時に入ります(Claude Code では再注入も)。反する編集で警告を出すには `violation_signal` を足し、拒否まで行うにはさらに `resolve_drift(action: "harden")` で hard にします。`drift_status` がその台帳で、各決定が いま守られているか(🔵)・ずれているか(🔴)・誰も確かめていないか(⚫)を示します。
|
|
238
|
+
|
|
239
|
+
## More
|
|
240
|
+
|
|
241
|
+
- [docs/README.md](docs/README.md) — index of the pages moved out of this README
|
|
242
|
+
- [Troubleshooting and FAQ](docs/troubleshooting.md) — skill not firing, Stop hook not recording, recall too long, resetting, DB size
|
|
243
|
+
- [How the memory is built](docs/memory.md) — the six layers, `read_smart` token savings, SQLite layout, comparison with Mem0 / Letta / Zep and Claude Code auto-memory
|
|
244
|
+
- [History](docs/history.md) — release highlights, roadmap, articles about the project
|
|
245
|
+
- [CHANGELOG.md](./CHANGELOG.md) — every release · [GitHub Releases](https://github.com/michielinksee/linksee-memory/releases)
|
|
246
|
+
|
|
247
|
+
## Support and license
|
|
248
|
+
|
|
249
|
+
- Issues: [github.com/michielinksee/linksee-memory/issues](https://github.com/michielinksee/linksee-memory/issues) (feature requests: the `enhancement` label)
|
|
250
|
+
- Security: [SECURITY.md](./SECURITY.md), or a private advisory on GitHub
|
|
251
|
+
- MIT — Synapse Arrows PTE. LTD. (Singapore)
|
|
252
|
+
|
|
253
|
+
<!-- Old section links, kept so deep links still land somewhere. -->
|
|
254
|
+
<a id="the-map"></a>The Map moved to [docs/drift-and-map.md](docs/drift-and-map.md).
|
|
255
|
+
<a id="reinjection-guard"></a>Re-injection Guard moved to [docs/guard.md](docs/guard.md).
|
|
256
|
+
<a id="uninstall"></a>Uninstall moved to [docs/install.md](docs/install.md#uninstall).
|
|
257
|
+
<a id="telemetry-opt-in-off-by-default"></a>Telemetry moved to [docs/telemetry.md](docs/telemetry.md).
|
|
258
|
+
<a id="other-editors--clis"></a>Other editors / CLIs moved to [docs/install.md](docs/install.md#other-editors--clis).
|
|
259
|
+
<a id="database-location"></a>Database location moved to [docs/install.md](docs/install.md#database-location).
|
|
260
|
+
<a id="architecture"></a>Architecture moved to [docs/memory.md](docs/memory.md#architecture).
|
|
261
|
+
<a id="troubleshooting"></a>Troubleshooting moved to [docs/troubleshooting.md](docs/troubleshooting.md#troubleshooting).
|
|
262
|
+
<a id="faq"></a>FAQ moved to [docs/troubleshooting.md](docs/troubleshooting.md#faq).
|