
Memstack
io.github.isiomaCPublished by GitHub account isiomaCv0.8.5Updated Oct 24, 2026
MCP server for persistent, searchable memory for AI agents.
Overview
MemStack gives AI agents persistent, searchable project memory: store, retrieve, summarize and prune what an agent learns across sessions.
- What you can do
- Store memories with tags, importance and actor IDs, and batch-store many at once
- Retrieve relevant memories by semantic, keyword or hybrid search, and assemble token-budgeted context for the LLM
- Summarize old memories, prune stale ones, merge, count, touch and delete memories
- Share one memory per project across Claude Code and Codex through a session-start hook
- Export and import full state for backups or migration between storage backends
- When to use it
- Use it when coding agents or your own agents keep forgetting project conventions and decisions between sessions, or when you want a self-hosted memory pipeline instead of stuffing history into the context window.
- Requirements
- Runs locally over stdio as an npm package (@memstack/mcp), installed alongside @memstack/cli and a storage driver such as better-sqlite3. Setup uses memstack init and memstack connect, which write a config file under ~/.memstack and register the server with Claude Code or Codex. An LLM provider key is optional; without one, memories are saved without topic tags.
Installation
In SourceWeft
- Open Memstack in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
MemStack
Persistent memory for AI agents. Claude Code and Codex share one memory per project, and your own agents get the same pipeline: store, retrieve, summarize, and prune.
Website and install guides: memstack.stalewell.com
[npm version] [skills.sh] [MCP Registry] [memstack MCP server – quality and maintenance score on Glama] [CI] [License: MIT] [MCP Reference]
Tell one agent how your project works. The other already knows. Claude Code learns a convention; a new Codex session recalls it and gets the task right:
Every session then starts with the project's key memories, and both agents save what you ask them to remember. How harness memory works.
Building your own agent?
@memstack/core is the runtime SDK; the Agent Skill teaches compatible coding agents how to integrate and operate MemStack correctly. Without -g, the skill installs into the current project (.agents/skills/, plus a .claude/skills/ link for Claude Code). Update it later with npx skills update.
The problem: AI agents forget. Every interaction starts from zero. You either stuff everything into the context window (expensive, slow, degrades output quality) or the agent has no memory of past conversations.
What MemStack does: A persistent memory pipeline that lives between your agent and the LLM. It stores every interaction, retrieves only what's relevant, summarizes old memories to save tokens, and prunes stale ones automatically. One method call, no infrastructure required.
Think of it as the open-source alternative to Mem0 — pluggable storage, bring your own LLM, zero vendor lock-in.
[memstack MCP server – quality and maintenance score on Glama]
Table of Contents
- Why MemStack
- Quick Start
- Harness Memory (Claude Code & Codex)
- The Memory Pipeline
- Real-World Use Cases
- Memory Type Reference
- Retrieval Strategies
- Embeddings
- Adapters
- Full API Reference
- Configuration
- Advanced Usage
- LongMemEval-S Retrieval Benchmark
- Development
- Publishing to npm
- Contributing
- License
Why MemStack
LLMs have context windows, not memory. The difference matters.
What MemStack handles that raw vector DBs don't:
- Summarization — compress 100 old interactions into one paragraph, keep meaning, save tokens
- Recency weighting — recent memories matter more; MemStack sorts them higher
- Importance scoring — not all memories are equal; high-importance ones survive pruning
- Deduplication — identical or near-identical memories are collapsed in context assembly
- Token budget —
compileContext()tells you how many tokens you're spending before the LLM call - Memory-type routing — interactions, summaries, observations treated differently at retrieval time
- Auto-pruning — old, low-importance memories clean themselves up
Quick Start
Claude Code and Codex
Persistent memory across agent harnesses: what you tell Claude Code, Codex recalls in the same project, and the reverse.
Then, in Claude Code: "Remember that this project uses Hono." In Codex, in the same repository: "What framework does this project use?" Codex answers Hono. See Harness Memory for how it works.
As a library
OpenAI
DeepSeek (no embeddings)
DeepSeek provides chat completions but has no embedding API. Use the OpenAI-compatible LLM adapter with baseURL and omit the embedding adapter — retrieval falls back to keyword + recency + importance ranking. You still get the full pipeline: store, summarize, prune, and compileContext.
OpenRouter / Together AI / any OpenAI-compatible API
Same pattern — change baseURL and defaultModel:
Store and retrieve
Harness Memory (Claude Code & Codex)
Coding agents forget everything between sessions, and they don't share what they learn with each other. MemStack gives Claude Code and Codex one memory per project: a decision made with one agent is known to the other, and to every later session.
How it works
- Saving. Each agent gets five MemStack tools (
memory_store,memory_retrieve,memory_get,memory_delete,memory_stats) through the MCP harness profile. When you say "remember that…", or the agent learns a durable fact, decision, preference, or rule, it callsmemory_store. MemStack asks your LLM for a few topic tags, so "uses Hono" can later be found by "which framework?". If tagging fails, the memory is still saved. - Recalling. A session-start hook loads the project's most important
memories into every new session, so the agent starts out knowing them.
During a session the agent calls
memory_retrievewith plain questions. Recall runs locally with keyword ranking (BM25 with stemming) and never calls the LLM, so it is fast and works offline. - Scope. Memories belong to the current project. Preferences that apply
everywhere can be saved as global (
scope: "global") and are recalled in every project. One project can never read or delete another's memories. - Safety. Agents don't get bulk or destructive tools, and the LLM key stays
in
~/.memstack/config.json(readable only by you), never in agent configs. Agents are told never to store secrets, and MemStack checks too: a memory that contains a credential (a private key, a cloud or source-host token, a JWT, a password in a connection string, apassword = "..."assignment) is refused before the LLM or the store sees it, and the error names the kind of secret without repeating it. The check is pattern-based, so a secret in a format it doesn't know will pass;MEMSTACK_SECRET_POLICY=redactstores the memory with[REDACTED:<kind>]in place of the secret, andoffdisables the check.
Commands
What connect changes
connect changes only these entries, backs up each file first, and
disconnect restores each file exactly:
The registered command is the memstack-mcp you installed, run by absolute
path, so it works even when the agent starts without your shell's PATH.
Restart Claude Code, or start a new Codex session, to load it.
Projects
The project ID comes from the repository itself, with nothing stored, so it stays the same across clones, worktrees, renamed remotes, moved folders, new machines, and storage switches:
- a pinned ID in
.memstack.jsonat the repository root (memstack project pin <id>; commit it to share it with your team); - otherwise, the repository's first commit;
- for shallow clones, the
originremote; - for repositories without commits, the git directory, and outside git, the folder. Memories saved before a repository's first commit move to the new ID automatically.
A fork shares its first commit with the original repository, so on one store
the two share memories until one of them runs memstack project pin.
Storage
Any supported store works; pick it in memstack init. MemStack never installs
storage drivers: install the one you need alongside @memstack/mcp.
Switching stores keeps project IDs; move memories with memstack export and
memstack import.
Troubleshooting
Run memstack doctor first; it checks the config file and its permissions,
the LLM key, the storage driver, each agent's registration, hook, and
guidance, and starts the server to confirm it answers.
- "memstack-mcp is not installed" or a missing driver: run the
npm install -g …command it prints. - Codex doesn't load memories at session start: approve the MemStack hook
in Codex with
/hooks. - Codex doesn't save when asked: check
memstack statusshows theAGENTS.mdguidance as present; reconnect if not. - Memories seem missing:
memstack projectshows which project you are in. Usememstack project merge <old-id>to bring memories from an old ID.
Details on the MCP server itself: docs/MCP_SETUP.md.
The Memory Pipeline
MemStack's core is a five-stage pipeline. Each stage can be used independently.
1. Store
Every agent interaction becomes a Memory with metadata that controls how it's retrieved, summarized, and pruned later.
2. Retrieve
Pull back what's relevant — by keyword, by meaning (semantic), by recency, or by importance.
Strategy behavior:
No embedding adapter? semantic and hybrid fall back to keyword matching + importance sort. No API costs, just less precise.
3. Compile Context
compileContext() takes retrieval results and assembles an LLM-ready system prompt — deduplicated, sorted by recency and importance, with a token estimate so you know the cost before calling the LLM.
compileContext() handles deduplication, token budgeting, and splits context into important-vs-recent sections. Without it, you'd be concatenating raw retrieval results and risking context-window overflow.
4. Summarize
When an actor has hundreds of interactions, retrieval gets expensive and context gets bloated. Summarization compresses old interactions into a single paragraph using the configured LLM.
Auto-summarization: Set summarizationThreshold in config (default: 100). Every 100th interaction for an actor triggers summarization automatically.
Warning: keepOriginals: false deletes the summarized memories. Set keepOriginals: true to preserve them alongside the summary.
Custom summarization prompt:
5. Prune
Not all memories deserve to live forever. Pruning removes low-value memories to keep storage and retrieval fast.
Auto-prune on every process() call by setting pruneStrategy in config:
Real-World Use Cases
Support Agent
RAG Pipeline
Multi-User Chatbot
Memory Type Reference
Types control retrieval behavior — compileContext() treats interaction and summary differently from observation. Use types to separate "what happened" from "what I know."
Retrieval Strategies
Four strategies, each with a purpose:
Choosing a strategy:
- Use
recentfor chatbots, ongoing conversations, anything time-sensitive - Use
importantfor long-running agents where signal-to-noise matters - Use
semanticfor RAG, document search, knowledge base queries - Use
hybridfor most agent memory — it balances meaning with significance
Keyword recall on any storage adapter
LexicalRetriever answers natural questions without embeddings or an LLM
call, and behaves the same on every storage adapter. It loads the memories
in the given actors through retrieve(), then ranks them in MemStack with
BM25 over content and tags, with stemming and prefix matching. When nothing
matches, it returns the most important memories instead.
Up to 2,000 memories per actor are ranked (candidateLimit). Only returned
memories are marked as accessed.
Embeddings
Embeddings power semantic search. They're optional — without them, retrieval uses keyword matching.
With embeddings vs Without embeddings
With embeddings (embedding adapter configured):
Without embeddings (no embedding adapter):
Batch embedding: storeBatch() sends all texts in one embedding API call, reducing cost and latency.
Vector dimensions and model compatibility
Different embedding models produce vectors of different lengths. Cosine similarity only works between vectors of the same dimension. If you change embedding models, existing vectors become incompatible — they can't be compared to new ones.
What happens if dimensions don't match: If you store memories with one model (e.g., 1536 dims) then switch to another model (e.g., 1024 dims), the storage adapter receives query vectors and stored vectors of different lengths. Cosine similarity between vectors of different dimensions is undefined — results depend on the storage backend's behavior. Most will either error, return empty results, or produce meaningless scores.
Recommendation: Pick one embedding model per storage instance and stick with it. If you need to switch models, create a new storage instance and re-embed from scratch.
DeepSeek users: DeepSeek has no embeddings API. If you use DeepSeek as your LLM, you must either:
- Omit the embedding adapter and use
"recent"or"important"retrieval strategies (no API costs, less precise) - Pair DeepSeek with a separate embedding provider (e.g., OpenAI for embeddings, DeepSeek for chat)
Adapters
MemStack is provider-agnostic. Every boundary is an interface — bring your own LLM, embedding model, and storage backend.
LLM Adapters
Used by summarize() and compileContext(). Ships with OpenAI, Anthropic, Ollama, and Groq built-in — and via baseURL, the OpenAI adapter works with any OpenAI-compatible API (DeepSeek, Mistral, Gemini, Together AI, Perplexity, Fireworks, xAI, and dozens more).
Embedding Adapters
Used by semantic retrieval. Ships with OpenAI and Cohere built-in — and via baseURL, the OpenAI adapter works with any OpenAI-compatible embedding API (Together AI, Voyage AI, Jina, Nomic, and more).
Storage Adapters
MemStack contains 18 storage-adapter implementations. Twelve are exported from @memstack/core; six remain experimental source implementations. Core has no runtime dependencies, and database clients are injected by callers.
Support levels:
- Production-ready means exported from the public package, covered by unit tests, and supported as part of the public API.
- Real-service E2E verified means the adapter also passes against its actual database implementation in
pnpm test:e2e. - Mock-tested means unit coverage uses an injected fake client rather than a live cloud service.
- Experimental means implemented in source but not exported from the published package.
Public package exports
Built-in (zero external deps):
Relational / SQL:
Vector databases:
Cache / KV:
Graph:
Experimental (mock-tested or missing an optional E2E capability)
These implementations are available to source contributors but are not part of the published package API.
Live cloud compatibility remains unverified for Pinecone, Upstash, Mem0, Zep, and Turso. Chroma's real-client E2E suite is skipped when its optional default embedding function is unavailable. LLM and embedding-provider tests use mocks; live-provider testing is opt-in and is not part of CI.
Quick-start per backend:
Custom storage:
Backend Comparison
Full API Reference
MemStack Client
Auto-behaviors run inside
process(), notstore().process()tracks a per-actor call count: summarization fires everysummarizationThresholdcalls, and pruning fires everypruneIntervalcalls (whenpruneStrategyis set).store()is the low-level write and never triggers these.
Memory Subsystem
All methods accessible via ms.memory.*:
Export / Import
Snapshot and restore full state for persistence, backups, or migration:
Each memory's original createdAt is preserved on import, so export → import is a lossless round-trip — safe for backups and cross-backend migration (e.g. disk → Postgres). All storage adapters honor a createdAt supplied on store()/storeBatch(); when omitted, they default to the current time.
Health & Close
Harness Memory API
The harness features are built on HarnessMemory, which works with any
storage adapter. Use it to build your own agent integration:
remember asks the LLM for topic tags (disable with autoTags: false); every
other method makes no LLM call. recall uses LexicalRetriever.
Configuration
Harness configuration file
The CLI and the MCP harness profile read ~/.memstack/config.json (or
$MEMSTACK_HOME/config.json), which memstack init writes with permissions
readable only by you:
Environment variables override the file one section at a time: any LLM
variable (OPENAI_API_KEY, ANTHROPIC_API_KEY, MEMSTACK_OPENAI_BASE_URL,
MEMSTACK_LLM_MODEL) replaces the whole llm section, and MEMSTACK_STORAGE
replaces the whole storage section, so a key is never sent to another
provider's URL.
Advanced Usage
Custom Storage
Implement StorageProvider for any database. The interface is 9 methods. See the reference section above for the full contract.
Optional members, none of them required:
capabilities: { multiProcess?, textSearch? }declares whether several processes can share the store safely and whethersearch()is native.search(query)provides native full-text search.LexicalRetrieveruses it whentextSearchis declared and ranks memories itself otherwise.retrieve()should honortouch: falseby returning memories without marking them as accessed.
SQLiteStorageAdapter enables WAL and a 5-second busy timeout so several
processes can share one database file. Set walMode: false or
busyTimeoutMs to change this.
Custom LLM / Embedding
Implement LLMProvider or EmbeddingProvider for any service:
Event Hooks
Monitor memory operations without modifying code:
LongMemEval-S Retrieval Benchmark
MemStack includes a Val benchmark pack for retrieval-only evidence-session recall on the public, cleaned LongMemEval-S split. The runner stores each question's sessions through MemStack's harness memory API, uses the local lexical retriever and in-memory storage, and does not call an answer model or judge. Secret scanning is disabled only for this benchmark's public corpus in the temporary in-memory store; do not use the runner with private data. Its recall metrics are not end-to-end QA accuracy and are not directly comparable to the official LongMemEval QA leaderboard. The published dataset is public, not a hidden evaluation set.
The dataset is not included in this repository. Validate the pack, then fetch only its explicitly named split with Val:
Val prints the SHA-256-addressed cache path. Pass it to the runner; --limit is a partial diagnostic run and must not be reported as the full benchmark:
The runner rechecks the exact declared size and SHA-256 before reading the file. It streams the JSON dataset, evaluates the default K values 1, 3, 5, and 10, excludes abstention questions marked with the upstream _abs question-ID suffix, and prints macro/micro evidence-session recall, question hit rate, and median/p95 retrieval latency. The upstream LongMemEval attribution and license are recorded in the manifest; this pack is not an official LongMemEval result.
Development
Setup & Tests
CI exposes a stable verification job. Configure that job as a required status check in GitHub branch protection for main.
Debugging
Use hooks for observability — MemStack has no built-in logging:
Common issues:
Inspecting state at runtime:
Publishing to npm
The @memstack scope requires --access public.
Contributing
Most needed contributions:
- LLM adapters: Google Gemini (native), Amazon Bedrock, Vertex AI
- Embedding adapters: local inference (transformers.js, ONNX)
- Benchmarks: retrieval quality, latency, cost comparisons
- Python port:
pip install memstack
Open an issue or PR at github.com/isiomaC/memstack.
License
MIT © MemStack
Source: README.md at commit 8518a3f
Tools
0Version history
4- v0.8.5LatestOct 8, 2026
- v0.8.1Oct 4, 2026
- v0.8.0Oct 3, 2026
- v0.7.2Sep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts