Skip to main content
Glama

⚓ memanchor

CI

Persistent memory for coding agents that knows when it's out of date.

Claude Code, Cursor and Codex forget everything between sessions. memanchor is a local MCP server that lets them save what they learn (decisions, conventions, gotchas) and recall it next time.

The difference: every memory is anchored to the files it describes. When those files change, recall flags the memory as STALE, so the agent re-checks before acting on outdated knowledge.

> recall "jwt signing"

1 memory, 1 stale (verify before relying on them)

#4 [decision] (STALE: src/auth/keys.ts changed; tags: auth, jwt)
JWTs are signed with RS256 so other services can verify them with the public key only.

Why

A wrong memory is worse than no memory. Most agent-memory tools store text and return it forever, even after the code it describes has been rewritten. memanchor treats memory like a cache that can be invalidated:

Plain notes / CLAUDE.md

Typical memory server

memanchor

Persists across sessions

✅

✅

✅

Searchable

grep

✅

✅ BM25 + stemming

Knows when a memory may be outdated

❌

❌

✅ file anchors

Scrubs secrets before saving

❌

rarely

✅

Bounded context cost

❌ whole file

varies

✅ token budget

Local, no cloud, no API key

✅

varies

✅

Related MCP server: apex-memory

Features

  • Staleness detection. remember(files: [...]) stores a content hash of each file. recall re-hashes and marks memories whose files changed or were deleted. confirm_memory re-anchors after the agent re-checks. list_memories(stale_only) finds memories to clean up.

  • Secret redaction. API keys (Anthropic, OpenAI, GitHub, AWS, Slack, Stripe, Google), JWTs, private keys, password= style assignments and credentials in connection strings are replaced with [REDACTED:type] before anything touches disk, and the agent is told what was scrubbed.

  • Relevance search. SQLite FTS5 with porter stemming ("migrating" finds "migrations"), prefix matching, and tags weighted into the BM25 ranking.

  • Token budget. Recall stops adding results at max_tokens (default 1500), so memory can't flood the context window.

  • Project isolation. One database, scoped per git repository. Paths outside the project are rejected.

  • Deduplication. Saving the same memory twice updates it instead of creating a copy.

  • Zero native dependencies. Uses Node's built-in node:sqlite. Nothing to compile.

Install

Requires Node.js 22.13 or later.

Claude Code

claude mcp add memanchor -- npx -y memanchor

Cursor: add to .cursor/mcp.json

{
  "mcpServers": {
    "memanchor": { "command": "npx", "args": ["-y", "memanchor"] }
  }
}

Any MCP client: run npx -y memanchor as a stdio server.

The project is the git repository of the directory the server starts in. If your client starts servers elsewhere, set MEMANCHOR_PROJECT=/path/to/repo. Memories are stored in ~/.memanchor/memory.db; override with MEMANCHOR_DB.

Tools

Tool

What it does

remember(content, kind?, tags?, files?)

Save a memory. kind is decision, convention, gotcha, fact or todo. files anchors it for staleness checks.

recall(query?, kind?, limit?, max_tokens?)

Ranked search; no query returns the most recent. Flags stale results.

confirm_memory(id)

The memory still holds after re-checking; re-anchor it to the current files.

forget(id)

Delete a wrong or obsolete memory.

list_memories(kind?, stale_only?)

Review everything, or just what needs re-checking.

The server also sends MCP instructions telling the agent to recall at the start of a task, remember what a future session would need, and verify stale memories before relying on them.

CLI

For humans who want to see what their agent remembers:

npx memanchor list            # all memories for this repo
npx memanchor list --stale    # only ones whose files changed
npx memanchor search "auth"
npx memanchor stats
npx memanchor forget 12

Evaluation

npm run eval measures whether recall puts the right memory first, on 24 memories from a fictional e-commerce backend and 24 queries in three categories (dataset). The baseline is substring matching, which is roughly what grepping a notes file gives you.

system

category

queries

hit@1

hit@3

MRR

substring

keyword

8

100%

100%

1.00

substring

morphology

8

50%

63%

0.59

substring

paraphrase

8

38%

38%

0.38

memanchor (BM25)

keyword

8

100%

100%

1.00

memanchor (BM25)

morphology

8

100%

100%

1.00

memanchor (BM25)

paraphrase

8

50%

63%

0.54

substring

all

24

63%

67%

0.66

memanchor (BM25)

all

24

83%

88%

0.85

Stemming and prefix matching fix word-form mismatches completely. Paraphrases are the weak spot: "where is the app hosted" shares no words with "Production runs on AWS ECS Fargate". That's the case for optional local embeddings (see roadmap). The dataset is small and hand-written, so treat these numbers as a regression check, not a benchmark.

Development

npm install
npm test        # type-check + 37 tests, including the built binary over stdio
npm run eval    # retrieval eval

Tests cover redaction patterns, staleness (changed, deleted, confirmed), dedup, path escapes, project isolation, FTS query sanitising, the token budget, and every tool through a real MCP client.

Roadmap

  • Optional local embeddings (hybrid BM25 + vector) to close the paraphrase gap

  • Anchor to symbols (a function, a config key) rather than whole files, so unrelated edits don't flag a memory

  • Memory decay: down-rank memories that are never recalled

  • Import existing CLAUDE.md / .cursorrules notes as memories

License

MIT

Available Tools

5 tools
confirm_memoryConfirm memoryA
Idempotent

Mark a stale memory as still correct after re-checking the code. Re-anchors it to the current files.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and idempotentHint=true, so the mutation and repeat-safety profile is already covered. The description adds useful behavioral context beyond that: the operation re-validates and re-anchors the memory to current files rather than rewriting its content. It does not mention permissions or return behavior, which is acceptable given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and followed by the concrete effect. No wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with annotations and no output schema, the description covers purpose and effect adequately, but it leaves the id parameter unexplained and does not say what the confirmation returns or whether it changes expiry/staleness state. Minimum viable but with a clear gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is one required parameter (id) with 0% schema description coverage, and the description never references it. With low coverage the description is expected to compensate, and it provides no information about which memory is identified or what the id refers to.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Mark a stale memory as still correct') and clarifies the effect ('Re-anchors it to the current files'), which separates it from remember/recall/forget without naming them. It is clear but does not explicitly differentiate itself from the sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear trigger condition: use this after re-checking the code for a memory that has gone stale. There is no explicit when-not guidance or named alternative (e.g. use remember to update instead), so it falls short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

forgetForgetA
DestructiveIdempotent

Delete a memory that is wrong or no longer applies.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is fully covered by structured data. The description adds only the intent condition for deletion and says nothing about permanence, whether related memories are affected, or confirmation of deletion—useful but not rich on top of the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the verb and rationale, and zero wasted words. Nothing could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter destructive tool with no output schema, the agent still lacks two things: how to acquire a valid id and whether the deletion is permanent or recoverable. The annotations cover the safety profile, but these operational gaps keep it at merely adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With one parameter at 0% schema description coverage, the description must carry the weight: it implies the id identifies 'a memory' but never says which identifier it is or where to obtain it (e.g., from recall or list_memories). The meaning is intuitive but not documented, leaving a real gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (delete) and resource (a memory), and the qualifier 'wrong or no longer applies' sharpens the intent beyond a bare delete. It is clearly distinguishable from remember/recall, though it never explicitly names or contrasts with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'A memory that is wrong or no longer applies' gives an explicit trigger condition for when to use the tool. There is no guidance on when not to delete (e.g., use confirm_memory to verify first) or on alternatives, so it stops short of full routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_memoriesList memoriesA
Read-only

List all memories for this project, optionally only one kind or only stale ones (for cleanup).

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo
stale_onlyNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true already tells the agent this is a safe read with no annotations contradicted. The description adds the useful project-scoping constraint and the cleanup intent behind stale_only, but says nothing about return format or ordering, so it is a modest addition over the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the primary behavior and appending the optional filters. It wastes no words, though the parenthetical '(for cleanup)' is the only place it earns extra meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description should ideally say what a listed memory contains and in what order they return, which it omits. Combined with no differentiation from the recall sibling, the definition is adequate but has clear gaps for an agent deciding how to call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning, and it does name both optional filters ('only one kind', 'only stale ones') and gives stale_only a purpose ('for cleanup'). The enum for kind supplies the concrete values, leaving only small gaps such as the exact meaning of 'stale'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('List all memories') plus a scope ('for this project'), so the core action is unambiguous. It does not, however, distinguish itself from the similarly named sibling 'recall', leaving an agent to infer which listing/retrieval tool to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It offers an implied usage context by noting that 'stale ones (for cleanup)' exists, which hints at the cleanup workflow. But it never states when to prefer this over recall, nor any prerequisites or exclusions, so guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recallRecallA
Read-only

Search this project's memories by keywords (BM25 full-text search). Call at the start of a task. Omit query to get the most recent memories. Results flagged STALE refer to files that changed since.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo
limitNo
queryNo
max_tokensNoApproximate budget for the result

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=true, so the description carries most of the burden and does add real value: the search mechanism, the no-query fallback behavior, and the meaning of the STALE flag in results. It omits anything about result shape beyond the STALE flag or any token-cost behavior implied by max_tokens, which is a modest gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each earning its place: purpose, when to call, fallback behavior, and result semantics. Front-loaded with the core action and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by explaining the STALE flag, which is the one non-obvious part of the return. Combined with the readOnly annotation, an agent has enough to call this safely; the remaining gap is the undocumented kind and limit parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%, so the description must compensate, and it only covers one of four parameters: query (keywords, omittable to get recent items). The kind enum values (decision, convention, gotcha, fact, todo) and limit are left entirely unexplained in both schema and description, so an agent cannot tell what filtering by kind actually does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search this project's memories') plus the retrieval mechanism (BM25 full-text search), which is concrete enough to distinguish it from the write-oriented siblings like remember and forget. It does not, however, differentiate itself from list_memories, since 'omit query to get the most recent memories' describes behavior that sibling plausibly also offers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear activation context: 'Call at the start of a task.' That is actionable guidance for an agent planning a workflow. It names no alternatives or when-not conditions (e.g. when to prefer list_memories or confirm_memory instead), so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rememberRememberA
Idempotent

Save something future sessions on this project should know: a decision and why, a convention, a gotcha, a fact or a todo. Keep it to one self-contained statement. Identical memories are updated, not duplicated.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNofact
tagsNoShort keywords, e.g. ['auth', 'jwt']
filesNoProject files this memory is about; it will be flagged stale when they change
contentYesThe memory, written so it makes sense without this conversation

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses the dedup/upsert behavior explicitly ('Identical memories are updated, not duplicated'), which is real behavioral context and consistent with idempotentHint=true. It does not contradict the annotations, though it adds nothing about what happens to a memory when its files change beyond the schema's own note.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, no filler, and the purpose is front-loaded before the constraints. Every sentence earns its place: purpose, content shape, dedup semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter write tool with no output schema, the description covers purpose, content expectations, and idempotency. The one gap is what a successful call yields (an id? a confirmation?) and how it interacts with confirm_memory, which an agent would have to infer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75% and the description meaningfully supplements it: it expands the kind enum into prose categories and, more importantly, explains the intended content of the required field and why it must be self-contained. tags and files are left to the schema, which documents them adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb ('Save') plus the exact resource and audience ('something future sessions on this project should know'), and it enumerates the accepted kinds. An agent can distinguish it from recall, forget, list_memories, and confirm_memory without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives strong positive guidance on what belongs in a memory (a decision and why, a convention, a gotcha, a fact, a todo) and the shape it should take ('one self-contained statement'). It never names a sibling alternative or a when-not condition, but the context is unambiguous enough that routing is easy.

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.

  1. 5 tool updatesv0.1.0
    • First observedconfirm_memory
    • First observedforget
    • First observedlist_memories
    • First observedrecall
    • First observedremember

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a distinct action: remember creates/updates, recall searches, confirm_memory re-anchors stale entries, forget deletes, and list_memories enumerates/filters. The boundary between recall and list_memories is clear because one is keyword search and the other is full listing with kind/staleness filters.

Naming Consistency4/5

All names use lowercase snake_case and are verb-oriented, but remember/recall/forget are bare verbs while confirm_memory/list_memories follow a verb_noun pattern. The inconsistency is minor and still readable.

Tool Count5/5

Five tools is well-scoped for a project-memory server. Each tool covers a necessary lifecycle operation without redundancy.

Completeness5/5

The surface covers the full memory lifecycle: create/update (remember), search/read (recall), list/filter (list_memories), re-validate stale entries (confirm_memory), and delete (forget). No obvious gaps remain for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Persistent memory for AI coding agents. Enables agents to save and recall decisions, patterns, bugs, and context across sessions via an MCP server with local SQLite storage.
    21 npm
    2
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A local, cross-editor MCP server that provides persistent memory for coding agents, capturing and recalling decisions, conventions, and fixes across sessions without API keys.
    -
  • A
    license
    A
    quality
    A
    maintenance
    MCP server that gives coding agents persistent, verified memory of codebase decisions, conventions, and skills, with evidence-based claims that are re-checked via git hooks and human-gated review. Enables memory search, propose/approve, chat harvesting, and critique across MCP-compatible tools.
    21
    51 npm
    1
    MIT