memory
A local-first, shared long-term memory server for AI agents, storing structured memories in one SQLite database and exposing 16 MCP tools for saving, searching, organizing, and maintaining them.
Save and edit memories —
save_memory,append_memory,update_memory,delete_memorywith categories, importance, tags, threads, entities, and expiry dates; edits preserve history and warn about duplicates.Search and read — ranked full-text search (FTS5 + BM25, stemming, ID/name handling) returning snippets, plus
list_memoriesandget_memoryfor full content with entities and history.Retrieve history —
get_memory_historyshows full edit/append history including replaced content.Track entities — link memories to people, services, repos, tickets, etc., then query with
find_by_entityandlist_entities.Follow threads and timelines —
get_thread,list_threads, andget_daily_summaryfor chronological grouping.Maintain the store —
find_duplicates,cleanup_expired(with dry-run), andget_statsfor health and overview.Share across agents — attribution per write, configurable auto-tags, shared policy instructions, and stdio or HTTP transport.
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., "@memory remember we chose Postgres 17 for billing-api for row-level security"
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 agents forget everything when a session ends, and different agents never see what the others learned. agentmemdb gives them one long-term memory: a local SQLite file, exposed as 16 MCP tools, that every agent on your machine reads and writes.
Shared. What Claude Code saves in the morning, omp can recall in the afternoon. Every write records which agent made it.
Local. One file on your machine. No cloud service, no API keys, no embedding model, no telemetry.
Cheap to recall. Ranked full-text search returns short snippets instead of whole memories, so lookups use few tokens.
Safe with many agents. Concurrent readers and writers, and a failed call can never leave the database locked.
See it in action
You → Claude Code We're moving billing-api from MySQL to Postgres 17 for row-level security. Remember that.
save_memory {"topic": "billing-api: move from MySQL to Postgres 17", "category": "decision", "importance": "high", …}
← {"status": "saved", "id": 1, "tags": "billing,database", "auto_tags_added": ["database"]}
You → omp (next day) Why are we moving billing to Postgres?
search_memory {"query": "why are we moving billing to postgres"}
← {"count": 1, "results": [{"id": 1, "topic": "billing-api: move from MySQL to Postgres 17",
"snippet": "…we need row-level security to isolate merchants, which MySQL does not offer…"}]}The examples walk through the full session: appending from a second agent, attribution, duplicate warnings, threads and entities, with real responses.
Related MCP server: hindsight-shared-memory
Quick start
Install it with any of these (macOS or Linux, Python 3.10+):
brew install harsh-gulhane/tap/agentmemdb # Homebrew
pipx install agentmemdb # or: pip install agentmemdb
uvx agentmemdb --check # or run it without installing, with uvagentmemdb --check shows where the database and config will live. Then connect your agents, using the server name memory everywhere so tool names match across clients (with uv, replace agentmemdb with uvx agentmemdb):
# Claude Code
claude mcp add memory -s user -- agentmemdb// omp: ~/.omp/agent/mcp.json
{ "mcpServers": { "memory": { "type": "stdio", "command": "agentmemdb" } } }Claude Desktop, Cursor, VS Code, Codex and HTTP setups are in getting started. To have agents save and search without being asked, add the memory policy prompt to your CLAUDE.md or AGENTS.md.
Features
Relevance search. SQLite FTS5 with stemming and BM25 ranking, where topic and tag matches rank highest. Handles IDs and names like
OPS-2406,PR #3056andexample.com, plain questions, and partial words.Structured memories. Categories, importance levels, tags, threads, entities (people, services, repos, tickets) and expiry dates.
Automatic tags. Regex rules in the config tag matching memories, e.g. anything mentioning Postgres or MySQL gets
database.Safe edits. Duplicate warnings on save, append mode, and an edit history that keeps replaced content.
One policy for every agent. Instructions in the config file reach every connected client's system prompt.
stdio or HTTP. One process per client, or one shared server over streamable HTTP on localhost.
Tools
Area | Tools |
Save and edit |
|
Search and read |
|
Entities |
|
Threads and timeline |
|
Maintenance |
|
Parameters and behaviour: tool reference.
Configuration
Optional. ~/.config/agentmemdb/config.json:
{
"db_path": "~/.local/share/agentmemdb/memory.db",
"auto_tags": { "database": "postgres|mysql|sqlite", "incident": "incident|outage" },
"instructions": "Search memory before answering questions about past work."
}Environment variables, path resolution, sharing and backups: configuration.
Development
git clone https://github.com/harsh-gulhane/agentmemdb && cd agentmemdb
make install # uv sync: editable install plus dev tools
make check # ruff, mypy --strict, pytestSee CONTRIBUTING.md for the project layout and workflow.
Security
agentmemdb stores memories unencrypted in a local file and makes no network calls. Read SECURITY.md for the security model, and report vulnerabilities privately through GitHub security advisories.
License
MIT © Harsh Gulhane
Available Tools
16 toolsappend_memoryA
Append additional context to an existing memory without replacing it. The new content is added with a timestamp separator. History is tracked.
Args: memory_id: The ID of the memory to append to content: New content to add (will be appended with a timestamp) source: Where this update came from (default: the connected client's name)
Inputs: content (required), memory_id (required), source. Returns: result
cleanup_expiredA
Find and optionally delete expired memories.
Args: dry_run: If true (default), only lists expired memories without deleting. Set to false to actually delete.
Inputs: dry_run. Returns: result
delete_memoryB
Delete a memory and its linked entities.
Args: memory_id: The ID of the memory to delete
Inputs: memory_id (required). Returns: result
find_by_entityA
Find all memories linked to a specific entity (person, service, account, etc.).
Args: entity_type: Type of entity (e.g. "person", "service", "account", "bucket", "ticket") entity_value: Value to search, substring match (e.g. "alice", "billing-api", "prod-db") limit: Maximum results (default: 25, max: 200)
Inputs: limit, entity_type, entity_value. Returns: result
find_duplicatesA
Find potentially duplicate memories. If topic is provided, finds memories similar to it. If no topic, finds groups of memories whose topics share most of their significant words.
Args: topic: Topic to check for duplicates (optional — if empty, scans all memories) limit: Maximum results or groups (default: 10, max: 100)
Inputs: limit, topic. Returns: result
get_daily_summaryA
Get memories created or updated on a specific local date, with new ones grouped by category.
Args: date: Date in YYYY-MM-DD format, in this machine's local timezone (default: today)
Inputs: date. Returns: result
get_memoryB
Get the full content of a specific memory including linked entities and edit history.
Args: memory_id: The ID of the memory to retrieve
Inputs: memory_id (required). Returns: result
get_memory_historyB
Get the full edit/append history of a memory, including content replaced by update_memory.
Args: memory_id: The ID of the memory
Inputs: memory_id (required). Returns: result
get_statsA
Get overview stats: total memories, breakdown by category, importance, top entities, active threads, expired count.
Inputs: no named parameters. Returns: result
get_threadA
Get all memories in a conversation thread, in chronological order.
Args: thread_id: The thread ID to retrieve (e.g. "incident-2026-03-24", "stock-analysis-march")
Inputs: thread_id (required). Returns: result
list_entitiesA
List all unique entities, optionally filtered by type. Useful to see what/who has been referenced.
Args: entity_type: Filter by type (optional, e.g. "person", "service")
Inputs: entity_type. Returns: result
list_memoriesA
List saved memories with optional filters. Expired memories excluded by default.
Args: category: Filter by category (optional) tag: Filter by a single tag, case-insensitive (optional) thread_id: Filter by thread ID to see all related memories (optional) limit: Maximum number of results (default: 25, max: 200) include_expired: Set to true to include expired memories (default: false)
Inputs: tag, limit, category, thread_id, +1 more. Returns: result
list_threadsA
List all conversation threads with their memory counts and latest activity.
Inputs: no named parameters. Returns: result
save_memoryA
Save a piece of context/memory for future conversations. Warns about likely duplicates (consider append_memory instead) and adds configured auto-tags.
Args: topic: Short title (e.g. "billing-api Postgres migration decision", "AAPL stock analysis") content: Detailed context to remember — include conclusions, data, links, action items category: One of: conversation, decision, incident, research, person, project, howto, config, other tags: Comma-separated tags (e.g. "postgres,database,billing") importance: One of: low, normal, high, critical source: Where this came from (default: the connected client's name, e.g. "claude-code") thread_id: Link related memories together with the same thread ID (e.g. "incident-2026-03-24") entities: JSON array of objects, e.g. [{"type":"service","value":"billing-api"},{"type":"person","value":"alice"}] expires_at: Optional expiry date (YYYY-MM-DD) after which this memory is less relevant
Inputs: topic (required), content (required), tags, source, +5 more. Returns: result
search_memoryA
Search memories by relevance: full-text search with stemming (topic and tag matches rank highest), falling back to substring matching. Returns a snippet per memory; use get_memory for the full text. Expired memories are excluded by default.
Args: query: Search query — plain words, hyphenated names, IDs, or FTS5 syntax (e.g. "tags:aws", "datadog OR sentry") category: Filter by category (optional) importance: Filter by minimum importance: low, normal, high, critical (optional) limit: Maximum number of results (default: 10, max: 100) include_expired: Set to true to include expired memories (default: false) full_content: Set to true to return full content instead of snippets (default: false)
Inputs: query (required), limit, category, importance, +2 more. Returns: result
update_memoryA
Update an existing memory. Only provided fields are updated. Use append_memory to add context without replacing. Replaced content is kept in the memory's history (see get_memory_history).
Args: memory_id: The ID of the memory to update topic: New topic (leave empty to keep existing) content: New content (leave empty to keep existing) category: New category (leave empty to keep existing) tags: New tags (leave empty to keep existing) importance: New importance (leave empty to keep existing) thread_id: New thread ID (leave empty to keep existing) expires_at: New expiry (leave empty to keep existing)
Inputs: memory_id (required), tags, topic, content, +4 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 16 tools
Most tools have clearly distinct roles (search vs. list vs. entity lookup vs. duplicate detection vs. stats), and descriptions explicitly cross-reference each other (e.g. append_memory vs. update_memory). The main overlap is between list_memories with a thread_id filter and get_thread, which retrieve similar data, plus get_memory vs. get_memory_history which differ only by whether history is included.
Every name follows a predictable snake_case verb_noun pattern (list_memories, get_memory, save_memory, update_memory, delete_memory, find_by_entity). The lone slight variation is cleanup_expired (verb + adjective, no noun), but it is still clear and idiomatic.
16 tools is at the upper edge for a well-scoped set, but each earns its place: core CRUD, search, entity lookup, threads, history, duplicates, stats, and expiry cleanup. A few aggregation tools (get_stats, list_threads, get_daily_summary) could arguably be folded into list/search filters, keeping it just shy of ideal.
Full lifecycle coverage: create (save_memory), read (get_memory, list_memories, search_memory), update (update_memory, append_memory), delete (delete_memory), plus history, entity linking/search, thread grouping, stats, duplicate detection, and expiry cleanup. No obvious dead ends for a memory-store domain.
Maintenance
Related MCP Connectors
Persistent memory layer for AI tools. Save and recall notes across Claude and other MCP clients.
Shared memory for your AI tools: tasks, notes and context every tool can read and write over MCP.
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Shared AI memory. ChatGPT, Claude, Cursor and any MCP app read and write the same memory.
Related MCP Servers
- AlicenseAqualityBmaintenancePersistent long-term memory for AI coding assistants. Local SQLite, no cloud - 16 MCP tools to store, search, relate, and consolidate typed memories with a confidence lifecycle, hybrid BM25 + semantic search, namespaces, a knowledge graph, and a built-in OS keychain credential vault.237MIT
- AlicenseNot gradedqualityCmaintenanceEnables all local Claude Code sessions, subagents, and other MCP clients to read and write one shared long-term memory over HTTP on localhost, so facts retained by one agent can be recalled by another. It extracts atomic facts, entities, and observations into an embedded local Postgres with ONNX embeddings and reranking, requiring no API key.MIT
- AlicenseNot gradedqualityCmaintenanceExposes a local SQLite-backed long-term memory to AI agents as MCP tools, letting them add conversations and documents, record dated facts with provenance, search and assemble context, and edit, inspect, or forget what was stored. It runs with your own embedding and LLM keys, so memories stay readable, exportable, and portable as plain markdown.MIT
- AlicenseAqualityBmaintenanceProvides AI coding tools with one local SQLite memory and rules store they can read over MCP, REST or the CLI, so facts, sessions and goals persist across sessions and shared rules are written into each tool's own instruction file. Runs entirely on your machine with no account, telemetry or network calls by default.414444 npm10Apache 2.0