ai-memory-mcp
Local, Markdown-first shared memory for AI coding agents: record decisions/progress/failures/handoffs as notes, then search and read them back across sessions.
Save a memory (
record_memory) — a decision, progress update, failure, or handoff, with project, title, content, tags, and your name inllm.Keyword search (
search_memory) — substring search over titles, content and tags; every word must match, works for CJK text, filterable by project/type/limit.Semantic search (
search_memory_semantic) — meaning-based lookup via local Ollama (nomic-embed-text); errors out if Ollama isn't running.Read a note (
read_memory) — full text of one memory by its path (e.g.my-app/2026-01-05-choose-db.md).Resume work (
get_handoff) — newest handoff summaries with full content; intended to be called first.Browse recency (
recent) — latest notes of any type, newest first, optionally per project.List projects (
list_projects) — every project that has at least one memory.Audit usage (
audit_usage) — who read what and when (tool, caller, project, query text; never result contents).Attribution — pass your own name in
llmon any tool so writes and reads are logged to the caller.Guardrails — a write guard refuses notes containing tokens/API keys, Taiwan phone/ID or Luhn-valid card numbers, and project/path names are restricted so agents can't write outside
notes/.Data portability — plain
.mdfiles under~/.ai-memory/notes/are the source of truth (hand-editable, committable); the SQLiteindex.dbis disposable.
Provides optional semantic search over the stored Markdown notes using a local Ollama embedding model, enabling meaning-based retrieval in addition to exact substring search.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ai-memory-mcp check my memory for what we decided about the database"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ai-memory-mcp
English | 繁體中文
Local, Markdown-first shared memory for AI coding agents, served over MCP.
Every session of every tool (Claude Code, Codex CLI, Copilot CLI, ...) starts with amnesia. This gives them one shared place to record decisions, dead ends and handoffs, and to look them up next time, so you stop re-explaining your project.
Status: feature-complete, provided as-is. This is a small tool I use myself. I do not offer support and I am not taking feature requests. Bug reports may go unanswered. Fork it freely (MIT).
Why this one
Plain Markdown is the source of truth. One
.mdfile per memory: readable, greppable, diffable, committable.The index is disposable. SQLite only accelerates search. Delete
index.dband it is rebuilt from your notes.Local and private. No cloud, no account. Optional semantic search uses a local Ollama model.
Any language. Substring search works for Chinese/Japanese/Korean text, not just space-separated words.
Auditable. Every read is logged (who, when, what query; never the results).
Related MCP server: mcp-chest-memory
Install
Requires Python 3.10+.
git clone https://github.com/bargisula/ai-memory-mcp.git
cd ai-memory-mcp
pipx install . # or: pip install .
ai-memory doctor # checks your setupThen register the server with your MCP client. The command is ai-memory-mcp (stdio transport):
# Claude Code
claude mcp add -s user ai-memory -- ai-memory-mcp
# Codex CLI
codex mcp add ai-memory -- ai-memory-mcpAny client that takes a JSON config (for example ~/.copilot/mcp-config.json):
{ "mcpServers": { "ai-memory": { "command": "ai-memory-mcp" } } }If you use uv, you can skip the install and point the client at
uvx --from git+https://github.com/bargisula/ai-memory-mcp ai-memory-mcp instead.
The server ships usage instructions to the client automatically (check the handoff first, record decisions and failures as you go), so no extra prompt file is required.
Tools
Tool | What it does |
| Save a note. |
| Substring search; every word must match. Returns short snippets. |
| Meaning-based search (needs Ollama, see below). |
| Full text of one note. |
| Newest handoff notes with full text. Call first when resuming work. |
| Latest notes of any type. |
| Projects that have notes. |
| Read audit log. |
Pass your own name in llm (for example "Claude") so entries and reads can be attributed.
Where your data lives
Default: ~/.ai-memory/ (override with AI_MEMORY_HOME).
~/.ai-memory/
notes/<project>/2026-01-05-choose-database.md <- the truth. Back this up / put it in git.
index.db <- disposable search index + audit logA note looks like this, and you can write or edit them by hand:
---
project: my-app
type: decision
llm: Claude
tags: database
ts: 2026-01-05T10:20:00+08:00
---
# Use SQLite
Single file, zero setup. Rejected Postgres: no concurrent writers needed.After hand edits, deletions or copying notes from another machine, run ai-memory reindex. (A missing index.db
is rebuilt automatically the first time the server starts.)
Configuration
All optional, all environment variables:
Variable | Default | Meaning |
|
| Data directory |
|
| Allowed note types, comma separated |
|
|
|
|
| Ollama embeddings endpoint |
|
| Embedding model |
|
|
|
Semantic search (optional)
ollama pull nomic-embed-text
ai-memory reindex --embed # embed notes written before Ollama was availableWithout Ollama everything else works; search_memory_semantic simply reports that it is unavailable.
Vectors are compared by brute force in Python, which is fine up to a few thousand notes.
Command line
ai-memory doctor check the installation
ai-memory reindex [--embed] rebuild the index from notes/
ai-memory handoff <project> print the newest handoff (see hook below)
ai-memory search "<words>" keyword search, JSON output
ai-memory audit read audit log, JSON output
ai-memory web [--port N] open the read-only audit page in your browserAudit page
ai-memory web serves a small page at http://127.0.0.1:8765 showing who read what and when, with filters for
caller, project, tool, status and query text. It is read-only, listens on 127.0.0.1 only, refuses requests whose
Host header is not loopback (DNS-rebinding protection), and follows your browser language (English or 繁體中文).
Make handoffs load automatically (Claude Code)
Relying on the model to remember to call get_handoff is fragile. A SessionStart hook guarantees it. In
.claude/settings.json of your project:
{
"hooks": {
"SessionStart": [
{ "hooks": [ { "type": "command", "command": "ai-memory handoff my-app" } ] }
]
}
}Security notes
Project names are restricted to letters, digits,
_,-,.; anything path-like is rejected, so a prompt-injected agent cannot write outsidenotes/.read_memoryis likewise confined tonotes/*.md.Notes are plain text on disk. Do not store secrets in memories. A write guard enforces this:
record_memoryrefuses (and writes nothing) when title, content or tags contain a token or API key (Telegram,sk-, GitHub, AWS, Google, Slack, JWT, private-key blocks,password=...-style assignments), a Taiwan mobile number, a checksum-valid Taiwan national ID, or a Luhn-valid card number. The refusal names the category, never the matched text. Add your own rules, one regex per line, to<data dir>/guard-block.txt(#starts a comment); every LLM sharing the data directory is covered. SetAI_MEMORY_GUARD=offto disable.The audit log stores tool, caller, project and the query text (first 500 characters), never result contents.
Limits (by design)
Single user, single machine. Concurrent writers are safe (files are created exclusively, SQLite runs in WAL mode), but there is no access control and no built-in sync. To sync, keep
notes/in a git repository.No edit or delete tool. Edit or delete the Markdown file, then
ai-memory reindex.Search is substring matching, not fuzzy or ranked by meaning (use the semantic tool for that).
Coming from a private predecessor?
The note format is unchanged: copy your old notes/ folder into AI_MEMORY_HOME and start the server. The index builds itself.
Development
pip install -e ".[dev]"
pytestLicense
MIT. See LICENSE.
Available Tools
8 toolsaudit_usageB
Who read what and when (newest first). Search result contents are not logged.
Inputs: llm, tool, limit, project. Returns: result
get_handoffA
Newest handoff summaries for a project, with full content. Call this first when resuming work.
project: project name limit: max summaries (default 3, newest first) llm: your name, for the usage audit log
Inputs: project (required), llm, limit. Returns: result
list_projectsB
List every project that has at least one memory.
Inputs: llm. Returns: result
read_memoryA
Read one memory in full. path is the value returned by other tools, e.g. "my-app/2026-01-05-choose-db.md".
Inputs: path (required), llm.
recentA
Latest memories of any type, newest first.
project: restrict to one project; empty means all limit: max results (default 10) llm: your name, for the usage audit log
Inputs: llm, limit, project. Returns: result
record_memoryA
Save one memory: a decision, progress update, failure, or handoff summary.
project: project name; letters, digits, '_', '-', '.' only (e.g. "my-app") type: one of decision / progress / failure / handoff (configurable via AI_MEMORY_TYPES) title: one-line title content: the details; multi-paragraph Markdown is fine llm: who is writing this (e.g. "Claude", "Codex"); strongly recommended tags: comma-separated keywords, optional
Inputs: type (required), title (required), content (required), project (required), +2 more.
search_memoryA
Keyword search over titles, content and tags. Every space-separated word must appear. Works for any language, including Chinese/Japanese substrings. Not FTS syntax: quotes and operators are treated as plain text.
query: words to look for project: restrict to one project; empty searches all type: restrict to decision/progress/failure/handoff; empty searches all limit: max results (default 10, capped at 100) llm: your name, for the usage audit log
Inputs: query (required), llm, type, limit, +1 more. Returns: result
search_memory_semanticA
Meaning-based search using local Ollama embeddings; finds related notes that share no keywords. Requires Ollama running with the nomic-embed-text model (see README); otherwise returns an error and you should use search_memory instead.
query: a natural-language description project: restrict to one project; empty searches all limit: max results (default 5) llm: your name, for the usage audit log
Inputs: query (required), llm, limit, project. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
The retrieval tools (search_memory, search_memory_semantic, get_handoff, recent) overlap in that they all return memories, but each has a clearly described purpose: keyword search, semantic search, handoff-specific retrieval, and recency-based listing. read_memory is distinct because it loads one exact memory by path. Some confusion is possible between the two search tools, but the descriptions draw a clear boundary.
Most tools follow a verb_object pattern: record_memory, read_memory, search_memory, get_handoff, list_projects, audit_usage. search_memory_semantic adds a modifier and 'recent' breaks the pattern by being a bare adjective rather than verb_noun. Overall the convention is consistent enough to be predictable.
Eight tools is well-scoped for a personal/agent memory server. Each tool covers a distinct aspect: writing, reading, searching, semantic search, handoff retrieval, recent activity, project listing, and audit. No tool feels redundant or bloated.
The server covers the core memory lifecycle well: recording, reading, searching, retrieving handoffs, and auditing usage. The main gaps are the lack of update/delete operations and no way to browse tags, though these may be intentional for an append-only memory store. Agents can complete typical workflows without hitting dead ends.
Maintenance
Related MCP Connectors
Hosted MCP memory for coding agents: persistent across sessions, editable markdown, team sharing.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Shared memory for your AI tools: tasks, notes and context every tool can read and write over MCP.
Shared AI memory. ChatGPT, Claude, Cursor and any MCP app read and write the same memory.
Related MCP Servers
- AlicenseAqualityBmaintenanceLocal, searchable project memory for AI coding agents. Markdown source of truth, MCP interface, safe structured updates315Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides a persistent, local-first memory for coding agents over MCP, enabling automatic recall and recording of past work, failures, and decisions to reduce repetition and token usage.MIT
- AlicenseBqualityDmaintenanceLocal-first memory server for AI coding agents that stores work sessions, tasks, and durable memories in Markdown files, exposed through MCP tools for session management and memory retrieval.1011 npm1MIT
- AlicenseNot gradedqualityCmaintenanceProvides persistent, local-first memory for coding agents with Markdown as the source of truth, exposed via CLI, loopback API, MCP, and Codex hooks for context retrieval and durable writes.MIT