The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the AI Agent Memory listing page.
Agent-agnostic persistent memory as an MCP Server — local-first: memories travel with your project in
.aamm/, shared across Claude Code / Qoder / Cursor.
An agent-agnostic persistent memory layer exposed as an MCP Server. Any MCP client — Claude Code, Qoder, Cursor — can reuse it. Memories live in each project's .aamm/ directory and travel with the project; different agents working the same project share one memory store, with a source_agent stamp distinguishing writers.
.aamm/chroma/doubao-embedding-vision.aamm/memories/<category>/<id>.md, human-readable and editableThe three layers are joined by id.
| category | use |
|---|---|
user | user preferences (tech background / dev habits / answer style) |
project | project knowledge (architecture / stack / layout / design decisions) |
process | work process (solved issues / bugs / debugging / lessons) |
agent | agent collaboration (what was done / handoff notes) |
From PyPI:
From source:
Requires Python 3.11+.
The embedding layer is a generic OpenAI-compatible client — Volcengine / SiliconFlow / OpenAI / any compatible service works. On first run a default config is generated at .aamm/config.yml; edit as needed.
embedding section of .aamm/config.yml)| field | meaning |
|---|---|
provider | label (informational only) |
model | embedding model name |
base_url | OpenAI-compatible endpoint |
api_key_env | which env var holds the key |
dim | vector dim (must match the model) |
Put the key in the project root .env, then edit the embedding section of config.yml.
Volcengine doubao-embedding-vision (default; Agent/Coding Plan keys must use the Plan endpoint /api/plan/v3 — standard /api/v3 returns 401)
.env: VOLCENGINE_API_KEY=...
SiliconFlow bge-large-zh (Chinese-text optimized)
.env: SILICONFLOW_API_KEY=...
OpenAI
.env: OPENAI_API_KEY=...
Any other OpenAI-compatible service: just fill in base_url / model / api_key_env / dim.
After switching embedding model, old vectors may mismatch in dimension; clear
.aamm/chroma/and re-remember, or runpython tests/rebuild_vectors.py.
recall uses three-way fused retrieval to maximize hit rate:
title + tags + content, so title/tag signal enters the vectorCandidates are expanded to top_k*3, then fused down to top_k. If the query contains FTS5 special characters (., *, ", -, ...), the keyword branch falls back to LIKE substring matching instead of erroring.
Besides searchable memories, aamm keeps a human-readable work journal. After completing a user request, the agent calls journal_entry() to log what was asked / what it did / any open question. Journals are for people reading a timeline; recall does not search them. Use search_journal() only as a fallback to recover "what happened in a past interaction".
Journals are written to .aamm/logs/:
journal.db — single SQLite store (the search source, spans all dates)YYYY-MM-DD.md — one Markdown file per day, append-only timelineMemory (8):
remember(title, content, category, tags?, scope?) — store (three-way sync, auto-embed)recall(query, category?, top_k=5) — fused retrieval (vector + keyword + title match)get_memory(id) — get onesearch_memories(category?, tag?, agent?) — structured filterupdate_memory(id, ...) — update (re-embed + refresh md)forget(id) — delete (three-way sync)list_memories(category?) — listwho_am_i() — current agent + project contextJournal (3):
journal_entry(question, answer_summary, key_points?, open_question?, session_id?) — log a timeline entrysearch_journal(query, date_from?, date_to?, agent?, limit=10) — fallback search over journalssetup_profile(user_name) — set the user name (shown in journals)From PyPI (no PYTHONPATH needed):
From a source clone, add -e PYTHONPATH=<clone dir>\ai_agent_memory_mcp:
Qoder / Cursor are the same — just change --agent.
MIT