Linksee Memory
About
Local-first agent memory MCP — Claude Code, Cursor, OpenAI Codex, and Gemini CLI share one SQLite brain. 6-layer structured memory (goal/context/emotion/implementation/caveat/learning), drift detection with pre-action re-injection guard, and an AST-aware diff cache saving 50-99%
Details
- Author
- michielinksee
- Downloads
- 341
- Categories
- Productivity, AI, Knowledge Base
Jump to
- 6-layer structured memory: goal / context / emotion / implementation / caveat / learning
- Drift detection (Intent Datadog) flags unrecorded divergences from declared decisions
- Re-injection guard re-surfaces locked decisions before the agent acts
- read_smart AST-aware diff cache saves up to 86% tokens on re-reads
- Full MCP surface: Tools + Resources + Prompts + Sampling + Roots + Elicitation
- Pain records (caveats) are never auto-forgotten
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
Linksee MemoryCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
Install the server with npx linksee-memory-setup. No further configuration or invocation commands are detailed in the README.
remember
Persist knowledge across sessions and AI tools (Claude, GPT, Cursor, Codex, Gemini). The only cross-agent memory that survives session boundaries. WHEN TO CALL: • The moment an error or failure occurs → layer: "caveat" (auto-protected, never forgotten) • When a decision is made or approved → layer: "learning" • When a goal is set or updated → layer: "goal" • When something new is learned → layer: "learning" • When the user says "remember this" / "覚えておいて" • After completing a task or receiving user approval REQUIRED PARAMS BY MODE: • Create (default): entity_name + entity_kind + layer + content • Update: memory_id (+ optional content, layer, importance) • Delete: memory_id + forget: true Importance ≥ 0.9 pins the memory (protected from auto-forgetting). Supports Japanese (日本語) and English.
recall
Your persistent memory across all AI tools. CALL THIS BEFORE STARTING ANY TASK to check for past caveats (pain records), decisions, and learnings — prevents repeating mistakes across sessions. Typical usage: recall({ query: "keywords" }) for search, recall({ path: "file.ts" }) for file history, recall() for overview. WHEN TO CALL: • Before starting any new task or touching a file • When the user mentions "before" / "前に" / "last time" / "remember when" • When an error occurs — check if you've seen it before • When making a decision — check for prior decisions on the same topic THREE MODES (auto-detected): • Search (default): provide query → returns memories ranked by relevance + heat • File history: provide path → returns complete edit history with user-intent context • Overview: omit all params → returns entity list sorted by momentum Works across Claude, GPT, Cursor, Codex, Gemini — one local SQLite file, nothing leaves your machine.
read_smart
Token-saving file reader with AST-aware diff caching. Use INSTEAD of the standard Read tool for ALL file reads — even first reads gain chunk metadata for future savings. • First read: full content + chunk metadata (enables future savings) • Re-read unchanged: ~50 tokens (99% savings) • Re-read modified: only changed chunks (50-90% savings) Especially effective for files >200 lines. Always prefer this over Read.
drift_status
Check what's drifting right now — the "Intent Datadog" for your product decisions. Returns a structured truth map showing which decisions/constraints/hypotheses are: 🔴 drift (unaccounted divergence from intent) 🟡 review (soft signal, awaiting human decision) ⚪ held (acknowledged, time-boxed, not forgotten) 🔵 aligned (reality matches intent) Nodes are classified into 4 species: • hypothesis → Decision Cards (decision journal format) • constraint → Rules (pass/fail checklist) • commitment → Heartbeats (cadence monitoring) • source_of_truth → Reference (stable anchors) WHEN TO CALL: • At session start — "what needs my attention?" • Before making a decision — check for existing anchors on the topic • After completing work — verify drift state changed • When the user asks about product health / what's broken / what's stale
where_am_i
Locate the current topic on the Current Truth Map and report "you are here" + blast radius — the per-turn re-anchor. Returns the matching Map node(s) + journey stage (discover → … → expand), the BLAST RADIUS (what becomes suspect if you change this — the must-stay-consistent-with / should-align-with / realizes dependents; e.g. editing the README implicates the LP), and the decision behind the node (linked anchor), if any. Three ways to call: • NO ARGS → auto-locates from the files you JUST edited this session (the zero-effort re-anchor — call it freely as you work). • query: "<topic>" → lexical locate by topic. • node_id: "<id>" → exact node. This is how you avoid optimizing one node while silently breaking its neighbors (change the spec → npm/Docs/LP must move too). Matching is lexical (no embeddings). WHEN TO CALL: • Right after editing files — call with no args to see what you just touched + its blast radius. • When the topic shifts — re-anchor to the new node. • When the user asks "what does changing X affect?" / "where does this fit?"
check_decision
Deep-dive into a specific decision/anchor — its state, premises, drift edges, and pending candidates. Returns the full context for one truth-map node: what was decided, why, what reality says, whether it's drifting, and what actions are pending. WHEN TO CALL: • When the user asks about a specific decision ("what happened with X?") • Before resolving a drift signal — understand the full picture first • When reviewing premises of a decision ("is this still true?")
declare_anchor
Declare a new decision, constraint, or prohibition as a truth-map anchor. Anchors are NORMATIVE claims: "we decided X", "Y is forbidden", "Z must always hold." The drift detector later checks these against committed reality. declare-don't-mine: anchors come ONLY from explicit human declaration, never from pattern extraction. WHEN TO CALL: • When the user makes a product decision ("let's go with approach A") • When a constraint is established ("never do X") • When a commitment is made ("we ship weekly") • When the user says "anchor this" / "record this decision"
resolve_drift
Record a resolution for a drifting anchor — the human feedback loop. 6 actions: • fix — "we fixed the code/reality to match intent" → state becomes aligned • supersede — "intent evolved, this is the new direction" → state becomes aligned • acknowledge — "we know, parking it for now" → state becomes held (with optional review date) • dismiss — "false positive, not actually drifting" → edges dismissed • harden — "re-injected but still violated, enforce it" → card_policy.gate_mode=hard (PreToolUse will BLOCK) • soften — "back off to a warning" → gate_mode=soft WHEN TO CALL: • After drift_status shows 🔴 drift or 🟡 review items • When the user says "that's fixed" / "ignore that" / "we changed direction" • When acknowledging a known gap with a review date
flag_proposals
Record orphaned proposals — options you presented that the user never addressed. Conversations are tree-shaped but experienced linearly. When you present 3 options and the user engages with only 1, the other 2 become "orphaned proposals" — unresolved decision branches that both you and the user lose track of. WHEN TO CALL: • When you notice the user engaged with only some of the options you presented • When the conversation shifted topic and earlier proposals were never resolved • At session end, review what you proposed vs what was addressed • When the user says "what else did we discuss?" or "何か忘れてない?" Each proposal becomes a review-state anchor on the dashboard — visible until the user decides. This is declaration, not mining: YOU are the curator recognizing what went unaddressed.
dream
Dreaming Memory — consolidate orphaned proposals against the North Star. Returns the project's North Star (direction/goals/ICP/phase) alongside unresolved proposals that agents flagged during conversations. YOUR job as the evaluating agent is to decide: • surface — genuinely important unresolved fork point given the current direction • dismiss — outdated, already implicitly resolved, or irrelevant to current goals Think like a General Doctor doing triage: the North Star is the patient's chart, each proposal is a symptom. Not every symptom needs treatment. WHEN TO CALL: • At session start to triage accumulated proposals • When the user asks "何か見落としてない?" or "what should we revisit?" • Periodically to prevent proposal backlog from growing stale After evaluation, call resolve_proposal for each candidate with your verdict. ALSO RETURNS: `distill_queue` — auto-captured memories whose content is still a RAW user utterance. Rewrite each via remember(memory_id, content) per the guide in the response (one-line what, true why, "distilled": true). Drain up to 8 per call — the SessionStart digest reminds you while the queue is non-empty. And `friction` — anchors re-surfaced at the gate yet still contradicted (resolve_drift action:"harden" to enforce).
resolve_proposal
Record your evaluation verdict for an orphaned proposal after dreaming. Call this after `dream` for each candidate you evaluated against the North Star. • surface — Keep visible on dashboard for human decision • dismiss — Remove from dashboard (outdated/irrelevant/implicitly resolved) Always reference the North Star criteria in your rationale.
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"linksee memory": {
"linksee-memory": {
"command": "npx",
"args": [
"-y",
"linksee-memory"
]
}
}
}
}
McpServers
{
"linksee-memory": {
"command": "npx",
"args": [
"-y",
"linksee-memory"
]
}
}
Local-first cross-agent memory MCP. 6-layer structured brain (goal/context/emotion/impl/caveat/learning) with token-saving file diff cache (86% measured savings on re-reads)
Your agent forgets everything when a session ends. Worse — it silently drifts from what you decided last week.
Linksee Memory catches when your project drifts from its own decisions— the option abandoned at a fork, the pipeline that quietly stalled, the code that contradicts what you agreed — and a re-injection guard re-surfaces the locked decisionbeforethe agent acts. Rules you've explicitly hardened get blocked.
Underneath sits a local-first cross-LLM memory MCP — one SQLite file thatClaude Code, Cursor, Windsurf, OpenAI Codex, and Gemini CLIall read from. Not just "what happened" butWHY: 6-layer structured memory with precision recall and an AST-aware diff cache (50–99% token savings on re-reads).
npx -y linksee-memory setup— one command, done.
🌐Landing page:linksee-site.vercel.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
Make it automatic: add"Use Linksee Memory"to your system prompt /CLAUDE.md.
Memory is the entry point. Tie it to amap.yamlof how your product fits together, and thelinksee-memory mapCLI 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
- 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)
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 thewhysurvives 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 singlecaveatmemory is what separates "flat fact storage" from "the agent actually remembers the WHY". linksee-memory stores it acrosssix explicit layersso 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 installspgvectorwithout 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.
- Declaredecisions as anchors:declare_anchor({ kind: "decision", statement: "We use FTS5, not vector search", violation_signal: ["pgvector", "embedding"] })
- The engine detectswhen committed code reality diverges from these anchors
- State derivationclassifies 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
Themake-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.
Anchors are classified into four species with different display formats:
Drift detection (above) checks individual anchors. TheMaplifts it to the whole product: amap.yamldescribing 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-contract
The blast radius isgraded—must fix togethervsshould alignvsfyi— 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 shownseparately— a hand-declaredsuspectthe 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 isfixable now in codevsexternal checks, and any deferral with no expiry (so "accounted-for" can't quietly become a drift graveyard).
- 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 anMCP tool, so a coding agent can re-anchor itself mid-task.
Commands:where·affects·explain·status·next·reconcile·inspect --json·blueprint. Add--lang jafor Japanese labels.
🛡 Re-injection Guard — enforce decisionsbeforethe action
Drift detection (above) ispost-hoc— it tells you reality divergedafterthe change lands. The re-injection guard is thepre-actionhalf: it re-surfaces the decision you lockedbeforethe 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 usedcp."Having the rule in context isn't enough — so the guard runsoutside the agent's volition, as a Claude Code hook:
It isfail-open by construction: any parse / DB / logic error surfaces nothing and lets the action through. Theonlything that ever blocks is an explicithardcontradiction on a decisionyoudeclared.
npx -y linksee-memory setupoffers to wire this into yourproject's.claude/settings.json(Step 4). To do it by hand, drop this block into.claude/settings.jsonat your project root — it points at the globally-installedlinksee-memory-guardbin, 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'sproject-scoped on purpose— the guard enforcesthisrepo'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 withdeclare_anchor(...); setcard_policy.gate_mode:'hard'on an anchor to make a contradictionblockinstead 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.
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 with11 toolsthat gives any AI agent structured memory + drift detection:
- 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 savingsviaread_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.
┌─────────────────────────────────────────────────────────────┐ │ 🎯 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 hit
Every memory is tagged withexactly one layer.caveat-layer entries are protected from auto-forgetting. Cold low-importance memories are auto-consolidated intolearningentries on server startup.
- 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 there-injection guardinto 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)
claude mcp add -s user linksee -- npx -y linksee-memory
Tools appear asmcp__linksee__remember,mcp__linksee__recall,mcp__linksee__read_smart.
CopiesSKILL.mdto~/.claude/skills/linksee-memory/. Agent auto-fires on phrases like "前に…", "また同じエラー", "覚えておいて", new task starts, file edits, etc.
{ "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.
Linksee Memory is a standard MCP server (stdio). Any tool that speaks MCP can connect:
{ "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-memory
[mcp_servers.linksee] command = "npx" args = ["-y", "linksee-memory"]
{ "mcpServers": { "linksee": { "command": "npx", "args": ["-y", "linksee-memory"] } } }
Add the same stdio command toclaude_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.
Default:~/.linksee-memory/memory.db. Override withLINKSEE_MEMORY_DIRenv var.
# 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 else
Nothing ever leaves your machine, so step 3 fully erases everything Linksee stored.
Previous versions exposed 3 tools — v0.8.0 added 4 drift tools that let agents query and act on product-level intent ↔ reality divergence; v0.10 added the fork-point trio for orphaned-proposal triage;where_am_iadds the Current Truth Map's per-turn positional re-anchor. The memory tools are unchanged.
Each entity (person / company / project / file / concept) can have memories across six layers. Since v0.4, each memory uses the3-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.
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)
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



