SimpleMem – Technical Briefing Repository: https://github.com/moses-y/SimpleMem
The Problem
LLM agents quickly exhaust context windows when they need to recall past interactions. Existing approaches either keep the entire dialogue (high token cost) or rely on costly iterative reasoning. The result is poor long‑term recall and expensive inference.
What This Does
SimpleMem implements a three‑stage “compression‑index‑retrieve” pipeline that stores dialogue facts in a compact vector store and serves them via a lightweight MCP (Memory‑Control‑Protocol) server.
- Core pipeline – See
core/hybrid_retriever.py(744 LOC) and its duplicates underMCP/reference/core/andSKILL/simplemem-skill/src/core/. TheHybridRetriever.retrieveentry point orchestrates the flow: 1._retrieve_with_planning→_analyze_information_requirements→chat_completion(model call). 2. Results are post‑processed byextract_json→_clean_json_string.
- Memory model –
models/memory_entry.pydefines theMemoryEntrydata class; it is imported by 20 other modules, making it the primary data contract.
- LLM client –
utils/llm_client.py(also duplicated inMCP/reference/utils/llm_client.py) provideschat_completion,_handle_streaming_response, and JSON extraction. It is the only module that talks to the external LLM service and is used by 15 callers.
- Vector store –
database/vector_store.py(and its MCP counterpart) implementsadd_entries,semantic_search, andkeyword_search. It opens a SQLite connection via_get_connection(used by 9 callers) and persists embeddings.
- MCP server –
MCP/server/http_server.pyruns a FastAPI‑style HTTP endpoint (run.pystarts it). Requests are routed throughMCP/server/mcp_handler.py, which builds aMemoryBuilderand aHybridRetriever.
- Skill wrapper –
SKILL/simplemem-skill/src/main.pyexposes the same API as a Claude skill, loading the local vector store defined inSKILL/simplemem-skill/scripts/cli_persistent_memory.py.
How It Is Wired
Execution begins at MCP/run.py → main (line 14). main imports MCP/server/http_server.py and starts the HTTP server. Each incoming request is handled by MCP/server/mcp_handler.py.to_dict, which:
- Calls
_get_client→utils/llm_client.py.__init__(creates the LLM client). - Instantiates
HybridRetriever(core/hybrid_retriever.py.__init__). - Calls
HybridRetriever.retrieve, which invokes:_retrieve_with_planning→_analyze_information_requirements→chat_completion(network + model).extract_json→_clean_json_string(JSON parsing).
The retrieval path reaches the vector store via database/vector_store.py._semantic_search (reads the SQLite DB).
A secondary CLI entry point is MCP/reference/main.py. The ask function (line 145) follows the same call chain but returns the answer directly to the caller instead of an HTTP response.
Blast radius:
models/memory_entry.py– 20 dependents, any change ripples through the entire codebase.utils/llm_client.py– 15 dependents, central to all model calls.database/vector_store.py– 10 dependents, touches the persistent store.
No circular imports were detected, and the internal call graph contains 363 resolved edges, confirming a mostly linear flow.
How To Use It
# 1. Clone the repo
git clone https://github.com/moses-y/SimpleMem
cd SimpleMem
# 2. Install Python dependencies (root + sub‑projects)
pip install -r requirements.txt
pip install -r MCP/requirements.txt
pip install -r MCP/reference/requirements.txt
pip install -r SKILL/simplemem-skill/requirements.txt
# 3. Start the MCP server
python MCP/run.py # listens on the default port defined in MCP/config/settings.py
# 4. Optional: use the reference CLI
python MCP/reference/main.py ask "What did we discuss about compression?"
Configuration lives in MCP/config/settings.py (e.g., OPENROUTER_API_KEY). The skill version reads the same key from SKILL/simplemem-skill/src/config.py.example. No Dockerfile or Makefile is present, so containerisation must be added manually if required.
Real‑World Use
A customer integrating SimpleMem into a chatbot can run the MCP server alongside the bot process. The bot forwards user utterances to http://localhost:<port>/ask. The server compresses the dialogue, stores the embedding, and on subsequent turns retrieves the most relevant facts with a single chat_completion call, reducing token usage by ≈ 70 % compared with naive context concatenation.
import requests, json
def ask_simplemem(question):
resp = requests.post("http://localhost:8000/ask", json={"query": question})
return resp.json()["answer"]
Code Health & Issues
- HIGH – Add CI workflow – 63 source files, no GitHub Actions or other CI configuration.
- MEDIUM – Enable Dependabot/Renovate – 4 requirement files, no automated dependency updates.
- MEDIUM – Move large binaries to LFS –
MCP/reference/fig/simplemem-new.mp4(20 MB) and a 10.9 MB spreadsheet are stored in Git history.
Additional observations from static analysis: deep nesting (max depth 7) in utils/llm_client.py and duplicated answer‑generator code across three locations. No lockfiles are present, making reproducible builds harder.
The Bottom Line
SimpleMem provides a concrete, modular implementation of lifelong memory for LLM agents, with a clear HTTP‑based MCP layer and a reusable skill wrapper. The codebase is functional but suffers from maintenance‑heavy duplication, missing CI, and large binary assets in the repo. It is suitable for teams that need a ready‑made memory service and are prepared to address the hygiene gaps before production deployment.