Linksee Memory
Linksee Memory is a local-first, cross-LLM MCP server that gives AI agents persistent structured memory, drift detection, and token-saving file caching — all stored in a single SQLite file (~/.linksee-memory/memory.db) shared across Claude Code, Cursor, Windsurf, OpenAI Codex, and Gemini CLI.
Core Memory Operations
Store memories (
remember) — Save information about entities (people, projects, files, concepts) across 6 layers:goal,context,emotion,implementation,caveat, andlearning. Pin important memories (importance ≥ 0.9) to protect them from auto-forgetting.Recall memories (
recall) — Full-text search with composite ranking (relevance × heat × momentum × importance), layer filtering, pagination, token budget control, andmatch_reasonsexplaining each result.Update memories (
update_memory) — Atomically edit an existing memory by ID while preserving referential integrity (preferred over delete + recreate).Delete memories (
forget) — Remove a specific memory by ID or run an auto-forgetting sweep;caveat,goal, and pinned memories are always protected.List entities (
list_entities) — Overview of all known entities sorted by recent activity, with optional filters by kind or minimum memory count.Consolidate cold memories (
consolidate) — Cluster and compress old, low-importance memories intolearning-layer summaries to reduce DB size; supports dry-run preview.
File-Aware Capabilities
Token-saving file reads (
read_smart) — Full content on first read; only changed chunks (or a ~50-token "unchanged" confirmation) on re-reads, saving 50–99% of tokens.File edit history (
recall_file) — Complete chronological edit history of a file across all sessions, including the user intent behind each change.
Memory Layer Reference
goal— What the user is working toward (protected from decay while active)context— Why this, why now (constraints, timing, people)emotion— User tone signals (frustration, excitement, etc.)implementation— How it was done, including what failedcaveat— "Never do this again" lessons (permanently protected)learning— Distilled patterns from consolidated cold memories
Memory Lifecycle
Importance scoring (0.0–1.0), heat/momentum ranking, Ebbinghaus-inspired forgetting curve, and auto-consolidation on startup (7-day threshold). Quality checks reject pasted assistant output or CI logs (bypassable with
force=true).
Planned integration for vector search capabilities via sqlite-vec once an embedding backend is chosen, enabling enhanced memory recall functionality.
Mentioned as one of the MCP servers configured in telemetry examples, indicating compatibility with Slack MCP server integration.
linksee-memory
Claude Code forgets everything when you start a new session. Your successor knows even less.
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.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.
npx -y linksee-memory setup— one command, on in every repo.
🌐 Landing page: linksee.app (includes non-developer onboarding for Claude Desktop / Cursor / Claude Code / OpenAI Codex / Gemini CLI) 📖 Docs: docs.linksee.app — full reference: the product map & drift, install, and all 11 tools
Questions this answers
These are the questions people actually type — measured, verbatim (2026-09-04). If yours is here, this is the answer.
Claude Code forgets everything when I start a new session. How do I make it remember decisions across sessions?
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.
Claude Codeがセッションをまたぐと過去の経緯を忘れてしまいます。記憶を持たせる方法を教えてください。npx -y linksee-memory setup の一回で入ります。新しいセッションは recall() の brief(注意すべきこと・いまどこか・未解決)から始まり、固定した決定は行動の直前に再注入されます。説明し直す必要はありません。
What is the best MCP server for persistent memory across AI coding agents?
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.
AIコーディングエージェント用の記憶MCPサーバーでおすすめはありますか?
正直に言うと、「セッションを跨いで覚える」だけなら CLAUDE.md で足ります(実測しました)。Linksee が要るのは、間違いかけたとき・方針を変えたとき・並行案件のどれが外れたかを知りたいとき、の3場面です。
I want one shared memory between Claude Code, Cursor, and OpenAI Codex. What tools exist for that?
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.
Claude CodeとCursorとCodexで同じ記憶を共有したいのですが、どうすればいいですか?
SQLite ファイル1つを全員で読みます。Claude Code / Cursor / Windsurf / Codex / Gemini CLI のどこで決めた決定も、他のエージェントの行動の直前に出てきます。
My AI agent keeps re-implementing things we already decided against. How can I detect that a codebase has drifted from past decisions?
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.
過去に決めた設計方針とコードがずれていないかを検出できるツールはありますか?
決定を宣言しておくと(remember({ content, anchor: {...} }))、それに反する編集の直前に警告(hardened なら拒否)が出ます。drift_status は「宣言と現実がずれた決定」を証拠つきで一覧します。
Is there a local-first, self-hosted alternative to Mem0 for agent memory?
Yes. No account, no API key, no cloud — one local file, MIT licensed. npx -y linksee-memory setup and it's on.
Mem0 vs Zep vs Letta for a coding agent's long-term memory — which should I pick?
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.
How do I stop Claude Code from repeating the same mistake it made last week?
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.
開発の意思決定履歴をMCPサーバーで残しておく定番のやり方はありますか?remember({ content, anchor: {} }) の1回で、記録と強制が同時に入ります。drift_status がその台帳で、各決定が いま守られているか(🔵)・ずれているか(🔴)・誰も確かめていないか(⚫)を示します。
Related MCP server: auxly-memory-cli
🪄 Three spells to remember
Say this | What happens |
"use linksee" | Recalls relevant memories before acting |
"linksee this" | Saves the decision / lesson right now |
"what's drifting?" | Reconciles reality against your locked decisions |
Make it automatic: add "Use Linksee Memory" to your system prompt /
CLAUDE.md.
🗺️ Not just memory — a product map
Memory is the entry point. Tie it to a map.yaml of how your product fits together, and the linksee-memory map CLI catches drift with file:line evidence:

The 30-second demo above: the README says --export. The code doesn't. Linksee catches it — and shows what else a change would touch.
npx -y linksee-memory map where README.md # this file belongs to the README node — and what it touches
npx -y linksee-memory map explain readme # README promises --export; the code doesn't implement it — drift, with evidence
npx -y linksee-memory map affects readme # changing the README also touches docs, the CLI help, and the npm listing→ see The Map for the full flow.
📣 As featured on
Zenn: あなたの Claude Code、 実は前回のセッションを完全に忘れている — 73 ♡ on Zenn, 165+ users on Hatena Bookmark, picked up by tech blogs + YouTube shorts (May 2026)
Zenn: あなたの MCP server、 実は Tools しか使ってない (5 blocks 全実装 / v0.3.0) — the 1% of MCP servers that implement all 5 blocks
Zenn: あなたの Claude memory、 実は Claude にしか残らない (5 LLM 横断する方法) — cross-LLM memory pattern (May 12, 2026)
Zenn: Glama listing で 3 週間止まった話 (5 つの罠と解決策) — npm + Glama deployment retrospective
「Cordex/Cursor/Code/Gemini 全部につなげられるから、 横断的にできてる MCP ってところがこれのすごいところ」 — Hatena Bookmark, May 2026 (165+ users)
🎬 See it in action
Drift, caught. Decisions don't survive session boundaries — but their consequences do. Ask any session:
You: What's drifting right now?
Agent: [calls drift_status]
28 anchors: ⚪ 1 held · 🔵 27 aligned
Needs attention:
⚪ HELD — "Focus on 4 areas: Recipe layer, agent-native API,
Japanese market, Agent Insights"
↻ Reopens 2026-07-04
Everything else is aligned — no unaccounted divergence.The memory underneath. Drift detection only works because the why survives the session boundary:
Without linksee-memory — Monday morning, new Claude session:
You: We deployed last week but it crashed. How did we fix it?
Claude: I don't have access to previous sessions. Can you describe
what happened and walk me through the problem?
[30 minutes of log-spelunking and re-explanation]With linksee-memory — Same question, different outcome:
You: We deployed last week but it crashed. How did we fix it?
Claude: Let me check my caveats...
🧠 [caveat] NextAuth sessions invalidate when JWT_SECRET
rotates — redeploy all affected projects in parallel.
(from session 2026-04-13, importance: 0.9)
Is this the deploy you're asking about? We hit it when
we rotated secrets mid-flow.
You: Yes, exactly. Let's not repeat that.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.
🔍 Drift Detection — "Intent Datadog"
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.
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.
How it works
Declare decisions as anchors:
declare_anchor({ kind: "decision", statement: "We use FTS5, not vector search", violation_signal: ["pgvector", "embedding"] })The engine detects when committed code reality diverges from these anchors
State derivation classifies each anchor:
🔴 Drift — reality diverges with no recorded resolution
🟡 Review — a soft signal awaits your decision
⚪ Held — you acknowledged the gap, parked it with a review date
🔵 Aligned — reality matches intent, or a recorded resolution explains the change
Resolve with
fix,supersede,acknowledge, ordismiss— plus two gates:harden(PreToolUse will block) andsoften(back to a warning)
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.
4-species taxonomy
Anchors are classified into four species with different display formats:
Species | Icon | Display Format | Example |
Hypothesis | 🧪 | Decision Card (journal format) | "We'll launch English-first on HN" |
Constraint | 🔒 | Rule (pass/fail checklist) | "All writes go through remember()" |
Commitment | 🔁 | Heartbeat (alive/dead) | "Ship a new version every week" |
Source of Truth | 📍 | Reference (stable anchor) | "MCP server runs on stdio, single SQLite" |
🗺️ The Map — linksee-memory map
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:
I'm touching this file — where is it on the map, and what else must move?
1. Where am I? — locate a file (or, with no argument, infer from your recent edits):
$ npx -y linksee-memory map where README.md
"README.md" belongs to this Map node:
readme [understand] convergence
changes ripple to:
must fix together (hard): lp, docs-site
should align (soft): onboarding, client-configs
fyi (may ripple): telemetry-contractThe blast radius is graded — must fix together vs should align vs fyi — so a wide ripple isn't flat noise.
2. Why is it in this state? — the diagnosis, with file:line evidence:
$ npx -y linksee-memory map explain readme
STATUS
declared: healthy (active)
reality: implemented / matches
verdict: declared and reality agree (verified)
EVIDENCE
✓ README's Tools section lists where_am_i
README.md:424 — found "where_am_i" in section "Tools"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.
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).
How it works
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).reconcilechecks each node's declaredrealityagainst the code (signal/regex/section_contains/ file checks) and overlays a verdict — reality overrides what you hand-declared, with evidence.where_am_iis also an MCP tool, so a coding agent can re-anchor itself mid-task.
Commands: where · affects · explain · status · next · reconcile · inspect --json · blueprint. Add --lang ja for Japanese labels.
🛡 Re-injection Guard — enforce decisions before the action
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.
It exists for one specific, infuriating failure mode (anthropics/claude-code#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:
Hook event | Fires on | What it does |
|
| Checks the pending action against your accepted anchors. A |
|
| Replays your locked decisions + open forks into the fresh session — killing the "groundhog day" amnesia where a new agent repeats last week's call. |
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.
Enable it
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.
--project-guard— this repo only, the old behaviour--no-guard— skip it
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.
To wire it by hand instead, drop this block into .claude/settings.json (project root, or ~/.claude/settings.json for every repo) — it points at the globally-installed linksee-memory-guard bin, so no build step is needed:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|compact",
"hooks": [
{ "type": "command", "command": "npx -y linksee-memory guard", "timeout": 15 }
]
}
],
"PreToolUse": [
{
"matcher": "Edit|Write|Bash",
"hooks": [
{ "type": "command", "command": "npx -y linksee-memory guard", "timeout": 8 }
]
}
]
}
}It's project-scoped on purpose — the guard enforces this repo's decisions, and you opt in per project rather than letting it deny tool calls everywhere (the Stop hook from setup, by contrast, is user-global). 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.
Developing linksee-memory itself? The repo dogfoods the guard via a (gitignored)
.claude/settings.jsonthat 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 publishednpx -y linksee-memory guardform above.
What it does
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.
It is a Model Context Protocol (MCP) server with 11 tools that gives any AI agent structured memory + drift detection:
Mem0 / Letta / Zep | Claude Code auto-memory | linksee-memory | |
Drift detection | ❌ | ❌ | ✅ intent ↔ reality divergence tracking |
Cross-agent | △ (cloud) | ❌ Claude only | ✅ single SQLite file |
6-layer WHY structure | ❌ flat | ❌ flat markdown | ✅ goal / context / emotion / impl / caveat / learning |
File diff cache | ❌ | ❌ | ✅ AST-aware, 50-99% token savings on re-reads |
Active forgetting | △ | ❌ | ✅ Ebbinghaus curve, caveat layer protected |
Local-first / private | ❌ | ✅ | ✅ |
Four pillars
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.
Cross-agent portability — single SQLite file at
~/.linksee-memory/memory.db. Same brain for Claude Code, Cursor, Windsurf, OpenAI Codex, Gemini CLI.WHY-first structured memory — six explicit layers (
goal/context/emotion/implementation/caveat/learning). Solves "flat fact memory is useless without goals".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.
🧠 The 6-layer structure
┌─────────────────────────────────────────────────────────────┐
│ 🎯 goal ← what the user is working toward │
├─────────────────────────────────────────────────────────────┤
│ 🧭 context ← why this, why now — constraints, people │
├─────────────────────────────────────────────────────────────┤
│ 💗 emotion ← user tone signals (frustration, etc.) │
├─────────────────────────────────────────────────────────────┤
│ 🛠 implementation ← how it was done (+ what failed) │
├─────────────────────────────────────────────────────────────┤
│ ⚠️ caveat ← "never do this again" · auto-protected │
├─────────────────────────────────────────────────────────────┤
│ 🌱 learning ← patterns distilled from cold memories │
└─────────────────────────────────────────────────────────────┘
│
▼
Ranked recall via relevance × heat × momentum × importance
Returns match_reasons explaining each hitEvery memory is tagged with exactly one layer. caveat-layer entries are protected from auto-forgetting. Cold low-importance memories are auto-consolidated into learning entries on server startup.
Quick Start — One Command
npx -y linksee-memory setupThis does everything:
Registers the MCP server with Claude Code
Installs the agent skill (teaches the agent when to recall/remember)
Configures auto-capture (every session saved to your local brain)
Offers to wire the re-injection guard into this project (pre-action decision enforcement)
Restart Claude Code, then just chat normally. Add "Use Linksee" to any prompt to trigger memory recall.
Manual setup (if you prefer step-by-step)
Install & register:
claude mcp add -s user linksee -- npx -y linksee-memoryTools appear as mcp__linksee__remember, mcp__linksee__recall, mcp__linksee__read_smart.
Install the skill (auto-invocation):
npx -y linksee-memory install-skillCopies SKILL.md to ~/.claude/skills/linksee-memory/. Agent auto-fires on phrases like "前に…", "また同じエラー", "覚えておいて", new task starts, file edits, etc.
Configure auto-capture (Stop hook):
Add to ~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "npx -y linksee-memory sync" }
]
}
]
}
}Each turn end takes ~100 ms. Failures are silent. Logs at ~/.linksee-memory/hook.log.
Other editors / CLIs
Linksee Memory is a standard MCP server (stdio). Any tool that speaks MCP can connect:
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"linksee": {
"command": "npx",
"args": ["-y", "linksee-memory"]
}
}
}Restart Cursor. Memory tools appear in the agent panel.
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"linksee": {
"command": "npx",
"args": ["-y", "linksee-memory"]
}
}
}codex mcp add linksee -- npx -y linksee-memoryOr add to ~/.codex/config.toml:
[mcp_servers.linksee]
command = "npx"
args = ["-y", "linksee-memory"]Add to ~/.gemini/settings.json:
{
"mcpServers": {
"linksee": {
"command": "npx",
"args": ["-y", "linksee-memory"]
}
}
}Add the same stdio command to claude_desktop_config.json:
{
"mcpServers": {
"linksee": {
"command": "npx",
"args": ["-y", "linksee-memory"]
}
}
}Config file: macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\. Restart Claude Desktop.
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.
Database location
Default: ~/.linksee-memory/memory.db. Override with LINKSEE_MEMORY_DIR env var.
Uninstall
# 1. Remove the MCP server registration
claude mcp remove linksee
# 2. Remove the hooks from settings.json (edit the file, delete the linksee entries):
# ~/.claude/settings.json → the Stop hook running "npx -y linksee-memory sync"
# <project>/.claude/settings.json → the SessionStart/PreToolUse hooks running "npx -y linksee-memory guard"
# 3. Remove the installed skill and all local memory (optional)
rm -rf ~/.claude/skills/linksee-memory
rm -rf ~/.linksee-memory # deletes all stored memory — nothing is kept anywhere elseNothing ever leaves your machine, so step 3 fully erases everything Linksee stored.
What's new in v0.9
Feature | Detail |
Re-injection guard | The pre-action half of drift detection. A Claude Code |
Shippable hook wiring |
|
What's new in v0.8
Feature | Detail |
4 drift detection tools |
|
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. |
4-species taxonomy | Anchors classified as hypothesis/constraint/commitment/source_of_truth with species-appropriate display formats. |
Resolution priority | When multiple resolutions exist for an anchor, the most recent one wins (prevents stale acknowledge from shadowing a newer fix). |
Feature | Detail |
3-tool unified surface | 8 tools → 3: |
Auto-consolidate | Consolidation runs automatically on server startup (non-blocking, 7-day threshold). No manual |
Deprecation guidance | Old tool names ( |
"Use Linksee Memory" trigger | Add "Use Linksee Memory" to any prompt to force memory recall — same adoption pattern as Context7. |
Claude Code Plugin |
|
Feature | Detail |
One-command setup |
|
Structured memory v2 | 3-axis classification (altitude × type × state) for every memory. Auto-extraction from sessions produces machine-scannable JSON, not raw chat dumps. |
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. |
Five MCP Blocks | Tools + Resources + Prompts + Sampling + Roots + Elicitation. Most MCP servers expose only Tools; linksee-memory implements all five primitives. |
6 Tools
Two pillars, one surface. Memory and drift each get the minimum; nothing else is exposed. Eleven tools bled model-dependent behaviour across Claude / GPT / Cursor / Codex / Gemini — six is what an agent can hold without a manual.
Tool | What it does |
| Start here. No arguments → the session brief: what needs attention, where you are on the Map, open loops, top entities. |
| Save / update / delete. |
| Token-saving file reader with AST diff caching. Re-read unchanged = ~50 tokens; modified = changed chunks only. |
| "What's drifting right now?" The truth map: 🔴 drift / 🟡 review / ⚪ held / 🔵 verified / ⚫ unverified, with the evidence for each. |
| Record a normative claim — |
| Close the loop. |
The five earlier names — where_am_i, check_decision, flag_proposals, dream,
resolve_proposal — are folded into the six above. They are hidden from tools/list but still
answer if called, so a skill or agent written against an older version keeps working.
LINKSEE_LEGACY_TOOLS=1 lists them.
CLI utilities
Command | Purpose |
| One-command setup: MCP server + skill + Stop hook + the re-injection guard for every repo ( |
| MCP server (stdio) |
| Claude Code Stop-hook entry point |
| Re-injection guard hook: |
| Batch-import Claude Code session JSONL history |
| Install the Claude Code Skill that teaches the agent when to call recall/remember/read_smart |
| Summary of the local DB (entity count / layer breakdown / top entities / top edited files). Add |
The 6 memory layers
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):
{
"title": "freee OAuth token expires in 24h",
"altitude": "implementation",
"type": "outcome",
"state": "done",
"what": "freee OAuth token expires in 24 hours. Must refresh proactively.",
"why": "freee uses short-lived tokens unlike most SaaS (usually 30-90 day expiry)",
"affects": ["src/integrations/freee/auth.ts"],
"next_action": null
}caveatmemories are auto-protected from forgetting (pain lessons, never lost).goalmemories bypass decay while the goal is active.statetracks lifecycle:open→decided→in_progress→done/stalled/superseded.
Architecture
A single SQLite file (better-sqlite3 + FTS5 trigram tokenizer for JP/EN) contains five layers:
Layer 1 —
entities(facts: people / companies / projects / concepts / files)Layer 2 —
edges(associations, graph adjacency)Layer 3 —
memories(6-layer structured meanings per entity)Layer 4 —
events(time-series log for heat / momentum computation)Layer 5 —
file_snapshots+session_file_edits(diff cache + conversation↔file linkage)
The conversation↔file linkage is the key. Every file edit captured by the Stop hook is stored alongside the user message that drove the edit. So recall({ path: "server.ts" }) returns "this file was edited 30 times across 3 days, and here are the actual user instructions that motivated each change".
Why the design choices
Local-first — your conversation history is private. Nothing leaves your machine.
Single file —
memory.dbis one portable artifact. Backup = file copy.MCP stdio — works with every agent that speaks MCP, no plugins per host.
Reuses proven schemas —
heat_score/momentum_scoreported from a production sales-intelligence codebase. Rule-based, no LLM dependency in the hot path.
Roadmap
✅ 3-tool unified surface (remember / recall / read_smart) — v0.7.0
✅ Auto-consolidate on server startup — v0.7.0
✅ Claude Code Plugin (
claude plugin add -- linksee-memory)✅ Five MCP Blocks (Tools + Resources + Prompts + Sampling + Roots + Elicitation)
✅ Stop-hook auto-capture for Claude Code
✅ JP/EN trigram FTS5
✅ One-command setup (
npx -y linksee-memory setup)✅ Structured memory v2 (3-axis classification: altitude × type × state)
✅ Cross-LLM: Claude Code, Cursor, Windsurf, OpenAI Codex, Gemini CLI
✅ Landing page (linksee.app)
✅ Drift detection engine + 4 MCP drift tools — v0.8.0
✅ 4-species truth map (hypothesis/constraint/commitment/source_of_truth) — v0.8.0
✅ Dashboard with Decision Register visualization
🔮 Obsidian plugin (read truth map in your vault)
🔮 Vector search via
sqlite-vec(already in deps, embedding backend pending)🔮 Cross-device cloud sync (Pro tier)
Comparison with Claude Code auto-memory
Claude Code ships a built-in memory feature at ~/.claude/projects/<path>/memory/*.md — flat markdown notes for user preferences. linksee-memory complements it:
auto-memory = your scrapbook of "remember I prefer X"
linksee-memory = structured cross-agent brain with file diff cache and per-edit WHY
Use both.
Security & privacy
linksee-memory runs locally and is built to read — and send — as little as possible.
Local-first. Memory is one SQLite file at
~/.linksee-memory/memory.db. No account, no cloud, no API key.Telemetry is opt-in and OFF by default.
setupasks once; nothing is sent unless you agree there (or setLINKSEE_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).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.Clean MCP transport. The server writes only JSON-RPC to stdout; all logs go to stderr.
Hooks are documented and removable.
setupadds a Stop hook (session capture) and an optional guard hook. They make no network calls by default, are time-bounded, fail-open (a hook error never breaks your session), and are listed under Uninstall.No shell-injection surface. Subcommands run via
spawnwith array args andshell: false, from a fixed allowlist;map.yamlis parsed with the safeyamlparser (no arbitrary tag execution).Supply chain. MIT, published from a single owner.
npx -y linksee-memoryruns the published package — pin a version in CI if you need reproducibility.
Found a security issue? See SECURITY.md.
Telemetry (opt-in, off by default)
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.
Enable
export LINKSEE_TELEMETRY=basic # opt in
export LINKSEE_TELEMETRY=off # opt out (or just unset the variable)
# `linksee-memory setup` also asks once and records your choice in
# ~/.linksee-memory/telemetry-consent (delete that file to be asked again).Exactly what gets sent (Level 1 contract)
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:
Field | Example | What it is |
|
| Random UUID generated locally on first opt-in. Stored at |
|
| Package version |
|
| How many turns the session had |
|
| How long the session lasted |
|
| Counts only |
|
| Names of MCP servers configured (from |
|
| Percent distribution of file extensions touched |
| counts | Tool usage counters |
What is NEVER sent:
❌ Conversation messages (user or assistant)
❌ File contents
❌ Entity names, project names, file paths, URLs
❌ Memory-layer text (goal / context / emotion / impl / caveat / learning)
❌ Authentication tokens, API keys, secrets
❌ Your IP address (only a one-way hash for abuse detection)
Why we ask
Aggregated MCP-usage data helps the KanseiLink 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.
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.
Pricing
Free forever.
linksee-memory is local-first and runs entirely on your machine. There is no hosted component you need to pay for. The SQLite DB lives in your home directory; backup = file copy.
No account, no credit card, no API key. Just install and use.
Troubleshooting
Verify the skill was installed:
ls ~/.claude/skills/linksee-memory/SKILL.mdIf absent, run
npx -y linksee-memory install-skill.Restart Claude Code. Skills are indexed on session start.
Check that the MCP is registered under the name
linksee(the skill expectsmcp__linksee__*tool names):claude mcp list | grep linkseeIf it's registered as something else, either re-register or edit
~/.claude/skills/linksee-memory/SKILL.mdto match.
Check the hook log:
cat ~/.linksee-memory/hook.logRun a manual test:
echo '{"session_id":"test","transcript_path":"/path/to/some.jsonl"}' | npx -y linksee-memory syncMake sure the
Stophook in~/.claude/settings.jsonpoints tonpx -y linksee-memory sync(not the old-import).
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:
npx -y linksee-memory import --allThe 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.
Reduce max_tokens:
recall({ query: "...", max_tokens: 800 }) // default is 2000Or narrow with entity_name and layer:
recall({ query: "...", entity_name: "my-project", layer: "caveat" })rm -rf ~/.linksee-memory # nuke everything; next run creates a fresh DBOr delete individual memories via remember({ forget: true, memory_id: <id> }).
Consolidation runs automatically on server startup (7-day threshold). It clusters old cold memories into compressed learning-layer summaries. Caveat and active-goal layers are always preserved.
If you want to force a manual consolidation, restart the MCP server — auto-consolidate triggers on every startup.
FAQ
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.
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.
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.
Three axes:
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.
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.File diff cache:
read_smarttool 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.
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:
Works across Claude Code, Cursor, OpenAI Codex, Gemini CLI (shared SQLite)
Structured 6-layer format makes recall explainable
Auto-consolidation compresses cold memories on startup; caveats are permanently protected
Yes — see tools/bench-read-smart.ts in the repo. The read_smart tool:
Hashes file content on first read, returns full content + chunk metadata (AST/heading/indent boundaries).
On re-read with unchanged mtime+sha256, returns
~50 tokensof "unchanged" confirmation instead of re-sending the file.On real edits, returns only the changed chunks as full content + unchanged chunks as metadata-only references.
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%.
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.)
Two mechanisms:
Ebbinghaus forgetting: cold low-importance memories decay naturally, eligible for auto-forget sweeps.
caveatlayer and memories withimportance ≥ 0.9are always protected.Auto-consolidation: runs on every server startup (7-day threshold). Compresses clusters of cold low-importance memories by entity into a single
learning-layer summary, then deletes the originals. No manual scheduling needed.
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.
Yes — any MCP-compatible client works:
Claude Code:
claude mcp add -s user linksee -- npx -y linksee-memoryClaude Desktop: add to
claude_desktop_config.json(see onboarding on the LP)Cursor: add to MCP settings in Cursor → Settings → Features → Model Context Protocol
OpenAI Codex:
codex mcp add linksee -- npx -y linksee-memory(or~/.codex/config.tomlwith[mcp_servers.linksee]block)Gemini CLI: add to
~/.gemini/settings.jsonmcpServers sectionChatGPT (web/mobile app): stdio MCP not supported by the consumer app — requires Remote MCP server over HTTPS (not yet available).
Custom agent: the MCP stdio protocol is documented at modelcontextprotocol.io
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 and you see every byte before opting in.
After install, in a new Claude session ask: "Can you remember that I prefer TypeScript over JavaScript? Use Linksee Memory." Claude should confirm it called mcp__linksee__remember and stored this. Then in a different session ask: "What languages do I prefer? Use Linksee Memory." It should recall via mcp__linksee__recall and return the preference with match_reasons showing why.
Support
Issues & bug reports: github.com/michielinksee/linksee-memory/issues
Feature requests: open an issue with the
enhancementlabelSecurity concerns: see SECURITY.md if present, or file a private advisory on GitHub
Company: Synapse Arrows PTE. LTD. (Singapore)
Changelog
v0.11.3 — Robustness + MCP hygiene (2026-06-16)
Corrupt-database recovery: if
~/.linksee-memory/memory.dbis unreadable, linksee preserves it asmemory.db.corrupt-<timestamp>and starts a fresh one (with a clear message) instead of crashing with a raw SQLite error. Old memories stay recoverable in the backup.recalltool description no longer suggests editing your system prompt — cleaner MCP citizenship.
v0.11.2 — More cold-start hardening (2026-06-16)
statsworks on a fresh database instead of crashing withno such table— it ensures the schema exists first (it may be the first command a new user runs).map --helpprints usage instead of trying to import a map.
v0.11.1 — Cold-start fixes (2026-06-16)
Run any CLI through the package name:
npx -y linksee-memory setup(andmap,sync,guard,stats,import,install-skill). A fresh user couldn't reach the standalone bins (linksee-memory-setup, …) vianpx— npx resolves package names, not sibling bin names — so the one-command install 404'd. The main bin now dispatches subcommands; the standalone bins remain as aliases.mapexits gracefully with a next-step message when there's nomap.yamlyet (was a raw stack trace — the exact state of a first-time user).serverInfo now reports the real package version (was pinned to an old string).
v0.11.0 — The Map: where_am_i + linksee-memory map (2026-06-15)
Memory is the entry point; the product map is the new surface. Drift detection grows up from individual anchors into a whole-product map you navigate from the CLI.
where_am_i(11th MCP tool) — locate the current topic/file on the Current Truth Map and get its blast radius. Call it with no args to auto-locate from your recent edits.linksee-memory mapCLI —where·affects·explain·status·next·reconcile·inspect --json·blueprint. Amap.yaml(git source of truth) describes how value reaches your user; the reconciler checks it against your code with file:line evidence. Bilingual: add--lang ja.Graded blast radius (
must fix together/should align/fyi), declared-vs-reality verdicts, and an anti-graveyard guard for accounted-for drift.Per-project keys so the Map handles many projects at once.
v0.8.0 — Drift Detection MCP Tools (2026-06-08)
3 tools → 7 tools. The biggest update since launch — agents can now detect, query, and resolve intent ↔ reality drift.
New tools:
drift_status— returns the truth map with 4-species classification and per-node drift statecheck_decision— deep-dive into a single anchor: state, edges, pending candidatesdeclare_anchor— record a decision/constraint/prohibition as a truth-map node (with v9 ProjectCoreNode fields)resolve_drift— close the feedback loop: fix / supersede / acknowledge / dismiss
New engine module:
truth-engine.ts— state derivation logic migrated from the dashboard into the MCP engine. Any MCP client can now query drift status without a dashboard.Resolution priority fix: when multiple resolutions reference the same anchor, the most recent one wins (by
resolved_attimestamp). Prevents a stale acknowledge from shadowing a newer fix.4-species classification: nodes classified by
decision_modeinto hypothesis / constraint / commitment / source_of_truth with display format guidance.
No breaking changes to existing memory tools. All 3 memory tools (remember, recall, read_smart) are unchanged.
v0.7.2 — Recall ergonomics + auto-edge detection + classifier precision (2026-05-30)
Quality pass on v0.7.0 / v0.7.1 — sharper day-to-day agent UX and cleaner data for the dashboard:
recalltoken discipline: drops the redundantcontent_rawfrom the response (parsedcontentwas already there — it was a 2× duplicate), and actually enforcesmax_tokensby greedy assembly that measures real serialized size (was a flat ~100 tok/memory estimate). Addsapprox_tokensto the response so the agent can see its budget usage. The same query that previously returned ~15,800 tokens for a 1200 budget now stays inside it.recallprecision: near-duplicate memories — same entity + near-identical core text, e.g. the same message captured under bothgoalandlearning— collapse to one in the result set. Composite weights adapt to query specificity: multi-term queries weight relevance higher so off-topic-but-pinned memories don't crowd narrow recalls.Capture dedup (write side):
session-extractornow produces AT MOST one memory per user turn, with prioritygoal[first_intent] > caveat > decision > context. A first-intent message containing decision words (e.g. "決めた" / "これで進めよう") is no longer double-saved as bothgoalandlearning.memory_edgesauto-detection: the previously-emptymemory_edgestable is now populated during the sleep-mode consolidation sweep.detectMemoryEdges()links a later DECISION memory to the most-recent earlier same-topic decision within an entity (chain, not clique) so the dashboard can render Pivot Chains. The default relation isextends— a same-topic later decision builds on, but does NOT deactivate, the earlier one. Explicit reversal markers (やめる / revert / instead of) producecontradicts; explicit replacement markers (の代わり / replaces / deprecate) producesupersedes. Prevents silent deactivation of still-valid decisions.inferType/inferStateprecision: chitchat acknowledgements ("そうだね" / "ありがとう"), pasted terminal/git/email content, and meta-noise no longer classify asdecision— they returnnote/openbefore pattern matching. The learning-layer default →decisionis gated by this guard. Real decisions (採用 / 決めた, even after an acknowledgement opener) survive.
No schema migration, no breaking API changes. Existing rows keep their stored content; the classifier improvements apply to new captures going forward.
v0.7.1 — Review fixes (2026-05-29)
Based on Opus 4.7 design review of v0.7.0:
P0 — Required params guidance:
remembertool description now includes "REQUIRED PARAMS BY MODE" section so LLMs know exactly which fields are needed for create vs update vs delete.P0 — Migration guidance: Deprecated tool names (
forget,recall_file, etc.) now return specific migration examples instead of generic errors.P1 — recall path+query merge: When both
pathandqueryare provided torecall, results from file history and memory search are merged into a single response.P2 — Auto-consolidate safety: Table existence check via
sqlite_masterbefore queryingconsolidationstable, preventing errors on fresh databases.
v0.7.0 — 3-Tool Unified Surface (2026-05-29)
8 tools → 3 tools. Following Context7's proven pattern of fewer tools = better cross-LLM consistency.
Breaking change: The following tools are removed from the MCP surface. Calling them returns a migration guide:
Old tool | New equivalent |
|
|
|
|
|
|
|
|
| Auto-runs on server startup (7-day threshold) |
New unified tools:
remember— create + update + delete in one tool. Mode is inferred from params.recall— search + file history + overview in one tool. Mode is inferred from params.read_smart— unchanged.
Other changes:
Auto-consolidate on server startup (non-blocking
setTimeout, 7-day threshold,sqlite_mastersafety check)Claude Code Plugin bundle (
claude plugin add -- linksee-memory)Deprecation errors include specific migration examples
All internal handler functions are preserved — this is a surface change, not a logic rewrite.
v0.2.0 — English-first launch readiness (2026-04-20)
Prepares the package for a broader (primarily English-speaking) audience on Reddit, Hacker News, and Anthropic Discord. No breaking API changes.
Bilingualized
SKILL.md(auto-invocation skill). The bundled skill thatlinksee-memory-install-skillcopies into~/.claude/skills/linksee-memory/SKILL.mdwas 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.Install-skill CLI output is bilingual: example test phrases shown after installation include both English and Japanese.
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 includelet's go,pivot,switch to,settled on,approved,doesn't work,stuck,same error again,hit an error,debug,broke,revert.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.
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.
Internal: SKILL.md now documents pairing with KanseiLink skill as an English workflow example.
No code changes to the MCP protocol surface; all existing MCP clients continue to work unchanged.
v0.1.1 — Pin threshold tweak (2026-04-19)
Based on real-world feedback that importance=0.95 memories were not
being treated as pinned despite intent.
Pin threshold lowered from
>= 1.0to>= 0.9. Memories withimportance >= 0.9are now exempt from the auto-forget sweep and surfacepinned: trueinrecallandrememberresponses. This matches the natural mental model ("0.9 = high importance = should survive cleanup") without requiring exact1.0.All existing memories with
importance >= 0.9(including older ones set to0.9or0.95) become pinned automatically — no migration needed.Updated tool descriptions and error messages to reflect the new threshold.
v0.1.0 — Major UX update (2026-04-18)
Based on one week of dogfooding, here's what changed:
New tools
update_memory— atomic edit with preservedmemory_id. Solves the "forget+remember breaks session_file_edits links" bug.list_entities— fast "what do I know about?" primitive for session init. Supportskind/min_memoriesfilters and returns layer breakdown.npx -y linksee-memory stats— local DB summary CLI.
recall enhancements
match_reasonsarray on each memory: e.g.["content_match_fts", "heat:hot", "pinned"].score_breakdownwith per-dimension scores (relevance / heat / momentum / importance).Pagination via
offset/has_more/stopped_by.limitparameter (hard cap, complementsmax_tokensbudget).bandfilter to request only hot/warm/cold/frozen memories.mark_accessed=falsefor preview queries that shouldn't bump heat.Layer aliases:
decisions→learning,warnings→caveat,how→implementation, etc.Fix: opportunistic refresh of stale entity momentum scores. Entities recalled >1 h after last remember() no longer return stale momentum.
remember enhancements
Quality check: rejects pasted assistant output / CI logs / stack traces unless
force=true.importance=1.0now implicitly pins the memory (survives auto-forget).Layer aliases accepted.
forget changes
Pinned memories (importance=1.0) now preserved alongside caveat-layer memories.
Clear error response when attempting to delete a protected or missing memory.
dry-run now includes
sample_ids_to_drop.
consolidate changes
dry_run: truepreview mode — reports cluster count + candidates without writing.
Infra
Fixed fresh-DB migration bug (was querying
metatable before it existed).Bumped to Node 20+ for structured language feature usage.
All changes are backward compatible — existing integrations continue to work. Server.ts version banner now reports v0.1.0.
Older versions
See GitHub Releases.
License
MIT — Synapse Arrows PTE. LTD.
Available Tools
8 toolsconsolidateA
Sleep-mode compression. Clusters cold low-importance memories by (entity, layer), summarizes each cluster into a single protected learning-layer entry, deletes originals, and runs a forget-sweep. Run at session end or on demand. Set dry_run=true to preview without writing.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | session | |
| min_age_days | No | Override the default 7-day minimum age for clustering (set to 0 to consolidate everything immediately, useful right after a bulk import). | |
| dry_run | No | Preview what would be compressed without modifying the DB. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the burden of disclosing behavior. It explains that the tool is destructive ('deletes originals') and runs a 'forget-sweep'. It mentions that results are 'protected learning-layer entries' and that dry_run previews without writing. While some terms like 'forget-sweep' are not further explained, the overall destructive nature and side effects are transparent. Score 4 for solid disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the primary action and listing key steps. Every sentence adds value: first defines the operation, second gives usage guidance. No fluff or redundancy. This is a model of concise yet informative description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description should explain what happens and what the output looks like. It covers the process (clustering, summarizing, deleting, forget-sweep) and mentions dry_run. However, it omits details on the 'forget-sweep' and what 'protected learning-layer entry' means. For a tool with 3 parameters and no output schema, this is reasonably complete, but leaves minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67% (2 of 3 params have descriptions). The tool description adds context around 'cold low-importance memories' which helps interpret the min_age_days parameter. It also reinforces dry_run usage. The scope parameter's enum values are not elaborated in the description, but the tool's domain implies session vs all. Overall, the description adds meaningful context beyond the schema, scoring a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: 'Sleep-mode compression. Clusters cold low-importance memories by (entity, layer), summarizes each cluster into a single protected learning-layer entry, deletes originals, and runs a forget-sweep.' It provides a specific verb (compress/cluster/summarize/delete) and resource (memories). This clearly distinguishes it from sibling tools like 'forget' (individual deletion) or 'remember' (saving).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly recommends when to use: 'Run at session end or on demand.' It also advises on dry_run usage. However, it does not explicitly state when not to use it or provide alternatives, such as using 'forget' for single-item deletion. The context is clear but lacks exclusionary guidance, scoring a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetA
Explicitly delete a memory by id, OR run auto-forgetting across all memories based on forgettingRisk (importance + heat + age). Caveat-layer, goal-layer, and pinned (importance>=0.9) memories are always preserved. Prefer update_memory for corrections — forget is destructive.
| Name | Required | Description | Default |
|---|---|---|---|
| memory_id | No | ||
| dry_run | No | Report what would be deleted without actually deleting. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the tool is destructive, specifies preserved memory types (caveat-layer, goal-layer, pinned), and mentions the dry_run capability via schema. However, the description does not detail the exact forgettingRisk formula or that deletion is irreversible, but the dry_run parameter is well-described in schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long, with the main action stated first. It is concise and free of unnecessary detail, efficiently communicating key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (two modes, preservation logic, destructive nature), the description covers essential aspects. It explains when to use each mode, what is preserved, and the destructive intent. No output schema is provided, but the description does not need to discuss return values as the tool's effect is primary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds semantic context for memory_id (explicit deletion) but does not explicitly mention dry_run. However, it enriches the understanding by explaining the two operational modes and preservation rules, which go beyond the schema's parameter descriptions. Schema coverage is 50%, but the description compensates with broader context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states two distinct modes: explicit deletion by ID and auto-forgetting based on forgettingRisk. It also specifies preservation of caveat-layer, goal-layer, and pinned memories. This distinguishes it from siblings like update_memory and remember.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises to prefer update_memory for corrections, indicating when not to use forget and providing an alternative. Implicitly guides when to use: for destructive deletion or auto-forgetting.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_entitiesA
List the entities currently known to this memory store, sorted by recent activity. Use at the start of a new session ("what do I know about?") before issuing specific recall queries. Cheaper than recall for the "give me an overview" question.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Filter by entity kind. | |
| min_memories | No | Only include entities with at least N memories. Default 1. | |
| limit | No | Max entities to return. Default 30. | |
| offset | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses sorting behavior and states it is cheaper than recall, but does not mention any specific permissions or side effects. For a list tool, this is adequate but not fully transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no redundancy. First sentence states purpose, second gives usage context, third adds cost comparison. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description explains return is list of entities sorted by recent activity. Mentions cost comparison and usage context. Could detail return format more but sufficient for low complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 75% of parameters with defaults and enum details. Description adds no additional meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'List the entities currently known to this memory store, sorted by recent activity' with specific verb and resource. It distinguishes from sibling tools like recall by noting it is for overview before specific queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises use at session start for 'what do I know about?' before specific recall queries. Compares cost to recall tool, providing clear context for when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_smartA
Read a file with diff-only caching. Returns: (1) full content + chunk metadata on first read, (2) "unchanged" + cached chunk list (~50 tokens) if mtime matches, (3) "unchanged_content" if mtime changed but sha256 matches (touched but not modified), (4) changed chunks with content + unchanged chunks as metadata-only if the file was truly modified. Use INSTEAD of Read for files you have read before — saves 50%+ tokens on re-reads.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute file path | |
| force | No | If true, return full content regardless of cache state |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses the caching behavior and all four possible return states based on file modification status, offering complete transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately concise and well-structured with numbered return cases. While informative, it could be slightly more compact without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description thoroughly explains all four possible return types and the effect of the 'force' parameter, making it complete for an agent to understand the tool's behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage with descriptions for both parameters. The tool description does not add additional semantic value beyond what the schema already provides, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads a file with diff-only caching and lists four distinct return scenarios. It explicitly distinguishes itself from an alternative 'Read' tool by advising when to use it instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'Use INSTEAD of Read for files you have read before — saves 50%+ tokens on re-reads', providing clear guidance on when to use this tool vs. an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallA
Retrieve memories relevant to the current context using full-text search (BM25) + entity-name match, re-ranked by a composite score (relevance × heat × momentum × importance). Returns only what fits in the token budget, with match_reasons explaining WHY each memory was returned. Opportunistically refreshes stale momentum scores for entities in the result set. Supports pagination via offset/has_more. Layer aliases accepted. Use at the start of any task that might involve prior work.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | What you want to remember (free-text, entity name, or FTS5 MATCH expression) | |
| entity_name | No | Optional — narrow to a specific entity | |
| layer | No | Optional layer filter. Accepts aliases (decisions/warnings/how/etc.) as well as canonical names. | |
| band | No | Optional — only return memories whose heat_band matches. | |
| max_tokens | No | Approx token budget. Default 2000. Either max_tokens or limit stops iteration (whichever fires first). | |
| limit | No | Optional hard cap on number of memories. Stops at min(max_tokens-budget, limit). | |
| offset | No | Skip this many top results (pagination). Use has_more from prior response to decide next offset. | |
| mark_accessed | No | Set false for preview / listing queries that should not bump heat. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description fully covers behavioral aspects: search method (BM25+entity), re-ranking composite score, token budget, match_reasons, pagination, and side effect of refreshing stale momentum scores. This is highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four concise sentences, each adding significant information. Starts with core action, then details, then usage guidance. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers retrieval mechanism, ranking, token budget, match_reasons, side effect, pagination, layer aliases, and usage context. Lacks explicit description of return format (fields of memory objects), but given no output schema, it mentions match_reasons, which is key. Still fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline 3. The description adds value by explaining the composite score, pagination using has_more, layer alias acceptance, and the token budget mechanism, which enrich understanding beyond individual parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves memories using full-text search and entity-name match, with specific re-ranking. It distinguishes from siblings by focusing on relevance to current context and mentions 'Use at the start of any task that might involve prior work', providing clear purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use ('at the start of any task that might involve prior work'). However, it does not mention when not to use or provide explicit alternatives among siblings. Still, the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recall_fileA
Get the COMPLETE edit history of a file across all sessions, with per-edit user-intent context. Returns: total edit count, daily breakdown, list of distinct user intents that drove the edits, and the linked memories. Use this when you need to understand WHY a file was modified historically — far more accurate than recall() for file-centric questions because it queries session_file_edits (every physical edit) instead of summary memories.
| Name | Required | Description | Default |
|---|---|---|---|
| path_substring | Yes | Substring to match against file_path (e.g. "search-services.ts" or full absolute path) | |
| max_intents | No | Max distinct user-intent snippets to return. Default 10. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses what data is returned (edit count, daily breakdown, intents, linked memories) and that it queries session_file_edits. However, it does not address potential issues like multiple file matches or performance implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences plus return list: efficient, front-loaded with key information, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 2 params, no output schema, and no annotations, the description explains return values (edit count, daily breakdown, intents, linked memories) but lacks details on format, error handling, or behavior for multiple matches.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with both parameters already described. The description does not add significant new meaning beyond what the schema provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'Get' and resource 'edit history of a file', emphasizes 'COMPLETE' and 'per-edit user-intent context', and distinguishes from sibling recall() by specifying it queries session_file_edits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use: 'when you need to understand WHY a file was modified historically' and contrasts with recall(), providing clear guidance on tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberA
Store a memory about an entity (person/company/project/concept/file) in one of 6 layers: goal (WHY), context (WHY-THIS-NOW), emotion (USER tone), implementation (HOW — success/failure), caveat (PAIN lesson, never forgotten), learning (GROWTH log). Use this when you discover non-obvious goals, unexpected failures, user preferences, or decisions worth preserving. Pasted assistant output or CI logs are rejected (use force=true only if you are sure).
| Name | Required | Description | Default |
|---|---|---|---|
| entity_name | Yes | Name of the entity this memory is about | |
| entity_kind | Yes | ||
| entity_key | No | Optional canonical key (email, domain, file path) | |
| layer | Yes | One of: goal / context / emotion / implementation / caveat / learning. Common aliases (why, decisions, warnings, how, ...) are accepted. | |
| content | Yes | The memory content (plain text or JSON) | |
| importance | No | 0.0-1.0. Set to 0.9 or higher to "pin" a memory (protects from forgetting even outside caveat layer). | |
| force | No | Bypass the paste-back/CI-log quality check. Only set when you are sure the content is original user or agent thought. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even without annotations, the description fully discloses behavioral traits: memory is stored in one of six layers, importance can pin a memory, and pasted output is rejected unless force=true. All behavioral aspects are transparent beyond what the schema provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured paragraph that front-loads the core purpose, then details layers and usage. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 params, 4 required, 6 layers, no annotations, no output schema), the description covers purpose, usage, layer semantics, quality check, and force flag. It is complete enough for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 86% schema coverage, the description adds significant meaning: explains each layer with its purpose (WHY, WHY-THIS-NOW, USER tone, HOW, PAIN lesson, GROWTH log), clarifies the importance field for pinning, and explains the force field bypassing quality checks. This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool stores a memory about an entity, specifies six layers (goal, context, emotion, implementation, caveat, learning), and distinguishes itself from sibling tools like recall, consolidate, forget, etc. The verb 'Store a memory' is specific and the resource (entity with layers) is well-defined.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('discover non-obvious goals, unexpected failures, user preferences, or decisions worth preserving') and when not to use ('pasted assistant output or CI logs are rejected'), with an alternative (force=true). Provides clear context for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_memoryA
Atomically edit an existing memory in-place. Preferred over forget+remember because it preserves memory_id, which matters for session_file_edits links and referential integrity. Use to correct facts, update deadlines in goal entries, refine caveats, or re-score importance. Caveat-layer memories can be updated but cannot have their protected flag removed.
| Name | Required | Description | Default |
|---|---|---|---|
| memory_id | Yes | The memory.id to update | |
| content | No | New content (plain text or JSON). If omitted, content is kept. | |
| layer | No | Move to a different layer (aliases accepted). If omitted, layer is kept. | |
| importance | No | New importance 0-1. Set to 0.9 or higher to pin. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, description discloses atomicity, preservation of memory_id, and referential integrity. It mentions caveat-layer constraints. Missing details on permissions or error behaviors, but adequate for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences. First sentence states core purpose and key benefit. Second sentence provides use cases and a constraint. No redundancy or unnecessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage, parameter details, and key behavioral traits (atomicity, referential integrity, caveat-layer limitation). Without output schema, return value is unmentioned, but overall completeness is high given the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but description adds value beyond schema: 'aliases accepted' for layer and 'Set to 0.9 or higher to pin' for importance. This enhances understanding beyond parameter names and types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it atomically edits an existing memory in-place, specifying what actions it performs (update content, layer, importance). It explicitly distinguishes itself from the forget+remember alternative by highlighting preservation of memory_id and referential integrity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use: for correcting facts, updating deadlines, refining caveats, re-scoring importance. It also states a limitation for caveat-layer memories regarding protected flags, implying when not to fully update.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.2.0- First observed
consolidate - First observed
forget - First observed
list_entities - First observed
read_smart - First observed
recall - First observed
recall_file - First observed
remember - First observed
update_memory
TDQS
Scored across 8 tools
Each tool has a clear, distinct purpose: memory storage (remember), editing (update_memory), retrieval (recall, recall_file, list_entities), deletion/consolidation (forget, consolidate), and file caching (read_smart). There is no overlap that would cause misselection.
Most tools follow a verb or verb_noun pattern (e.g., consolidate, forget, list_entities, recall, recall_file, remember, update_memory). 'read_smart' breaks this pattern with a verb_adjective form. Overall, the naming is mostly consistent with minor deviations.
With 8 tools, the count is well within the ideal range for a memory management server. Each tool serves a necessary function without being redundant or excessive.
The tool set covers the core CRUD operations for memories, along with consolidation and file-specific retrieval. A direct 'get_memory_by_id' tool is missing, but recall can retrieve specific memories, so the gap is minor and workable.
Maintenance
Related MCP Connectors
shared AI-context layer for teams — persistent memory your agents search and update over MCP
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Related MCP Servers
- AlicenseAqualityBmaintenanceGives your AI persistent memory across conversations. Stores facts automatically, finds them by meaning using hybrid search with query expansion, and organizes everything into topics without manual tagging.181MIT
- AlicenseNot gradedqualityAmaintenanceLocal-first, file-based memory layer for AI agents — one shared Markdown vault across Claude, Codex, Gemini, Cursor and any MCP client. Provides read/write memory tools with an audit trail, per-agent trust levels, and Git sync; no cloud and no lock-in.2MIT
- FlicenseNot gradedqualityCmaintenanceLocal-first cross-agent memory for AI coding agents. Persistent, shared memory over MCP — what you tell one agent can be recalled by another — with all data stored in a single local SQLite file, no cloud and no API keys.-
- AlicenseNot gradedqualityDmaintenanceLocal-first AI memory layer with hybrid retrieval and brain-inspired namespaces. Enables agents to save, search, and manage memories directly via MCP tools.5MIT