Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
{
"mcpServers": {
"bsahane-memory-mcp-server": {
"command": "uvx",
"args": [
"memory-mcp-server"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 26, 2026Memory MCP Server
A Model Context Protocol (MCP) server that gives AI agents persistent memory. Memories are stored in a local SQLite database (auto-created, zero-config) and exposed through forty tools following a tools-first architecture. Built on the template-mcp-server production scaffold (FastMCP + FastAPI, structured logging, containers, OpenShift manifests, CI).
Features
- 40 MCP tools across four domains: memory, tasks, time (reminders/alerts), dashboard
- Seven memory tools: store, get, search, list, update, delete, projects
- Seven todo tools: create/search/list/get/update/complete/delete with priority and due dates
- Eight kanban tools: boards with configurable columns; card add/move/update/delete
- Seven tracker tools: status trackers whose entries roll up into progress metrics
- SQLite persistence via aiosqlite — single file, tuned WAL baseline, auto-created
- Full-text keyword search — whole-word, porter-stemmed matching over an FTS5 index, ranked by relevance (best match first)
- Tags & metadata on memories and todos
- FastMCP + FastAPI with multiple transports (HTTP, SSE, streamable-HTTP)
- Pydantic configuration via environment variables
- Structured JSON logging with structlog
- OAuth integration (disabled by default; see
docs/authentication.md) - Container-ready (Red Hat UBI base image) and OpenShift manifests included
Search & storage behavior
Search (memory_search, todo_search) matches whole-word tokens over a
porter-stemmed full-text index: partial words never match (querying check
will not match checklist), punctuation and operators are treated literally,
and results are ranked by bm25 relevance — strongest match first, newest first
on ties. Note that unicode61 tokenization treats a whole CJK sentence as a
single token, so whole-word matching assumes space-delimited scripts.
Databases run in WAL mode with synchronous=NORMAL: recently committed
transactions can be lost on an OS crash or power failure (an accepted tradeoff
for notes/tasks — not suitable as a system of record). Steady-state WAL size
is bounded by wal_autocheckpoint (~1000 pages ≈ 4 MiB);
journal_size_limit (8 MiB) only lets SQLite truncate the WAL file back once
checkpoints free it. Maintenance (PRAGMA optimize + a
wal_checkpoint(TRUNCATE) pass) runs inline in the reminder poll loop every
tenth tick and may briefly delay a tick; it is bounded by the per-hook
timeout and the database busy timeout.
Quick Start
git clone https://github.com/redhat-data-and-ai/memory-mcp-server
cd memory-mcp-server
make install # creates venv, installs deps + pre-commit hooks
make local # starts server on localhost:5001
Verify in another terminal:
curl http://localhost:5001/health
Manual setup (without Make):
# Create venv and install
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pre-commit install
# Configure and run
cp .env.example .env
memory-mcp-server
# Verify
curl http://localhost:5001/health
Tools
Memory
| Tool | Purpose |
|---|---|
memory_store(content, tags?, metadata?) | Persist a new memory; returns its id |
memory_get(id) | Fetch one memory by id |
memory_search(query, limit?, project?, output_format?) | Whole-word keyword search over content, ranked by relevance |
memory_list(limit?, offset?, tag?) | Browse memories newest-first |
memory_update(id, content?/tags?/metadata?) | Partially update a memory |
memory_delete(id) | Remove a memory by id |
Todos
| Tool | Purpose |
|---|---|
todo_create(title, description?, priority?, status?, due_date?, tags?) | Add a structured task |
todo_search(query, limit?, offset?) | Whole-word keyword search over title/description, ranked by relevance |
todo_list(status?, tag?, limit?, offset?) | Browse todos with filters |
todo_get(id) / todo_update(id, ...) / todo_complete(id) / todo_delete(id) | Manage individual todos |
Kanban
| Tool | Purpose |
|---|---|
board_create(name, description?, columns?) | New board; defaults to backlog/todo/in_progress/done |
board_list() / board_delete(board_id) | Enumerate or tear down boards |
board_view(board_id) | Full board state grouped by column |
card_add(board_id, title, ...) / card_move(card_id, column, position?) | Place and reorder work |
card_update(card_id, ...) / card_delete(card_id) | Edit or remove cards |
Reminders & Alerts
| Tool | Purpose |
|---|---|
reminder_create(title, due_at, notes?, repeat?) | Schedule a future alert (none/hourly/daily/weekly repeats) |
reminder_get(id) / reminder_update(id, ...) | Inspect or edit a schedule |
reminder_list(status?, limit?, offset?) | Soonest-due first |
reminder_cancel(id) / reminder_snooze(id, minutes?) / reminder_delete(id) | Manage schedules |
alert_list(acknowledged?, limit?) / alert_ack(id) / alert_ack_all() | Review and clear fired alerts |
A background scheduler converts due reminders into alerts server-side;
query them at session start with alert_list(acknowledged=false).
Dashboard
| Tool | Purpose |
|---|---|
overview() | Cross-domain counts, unacked alerts, and what's due next |
Trackers
| Tool | Purpose |
|---|---|
tracker_create(name, description?) / tracker_list() / tracker_delete(id) | Manage trackers |
entry_add(tracker_id, name, status?) / entry_update_status(entry_id, status) / entry_remove(entry_id) | Track items (not_started/in_progress/blocked/done) |
tracker_status(tracker_id) | Progress: total/done/percent plus per-status counts |
All tools return {status: "success" | "error", ...} dictionaries and never
raise across the tool boundary.
Configuration
| Variable | Default | Description |
|---|---|---|
MEMORY_DB_PATH | ./data/memory.db | SQLite database file (auto-created, parent dirs included) |
REMINDER_POLL_SECONDS | 30 | Background scheduler interval for firing due reminders |
MCP_HOST | localhost | Server bind address |
MCP_PORT | 5001 | Server port (1024-65535) |
MCP_TRANSPORT_PROTOCOL | http | Transport protocol (http, sse, streamable-http) |
MCP_SSL_KEYFILE / MCP_SSL_CERTFILE | None | SSL key/certificate for HTTPS |
ENABLE_AUTH | False* | OAuth authentication (see docs/authentication.md) |
PYTHON_LOG_LEVEL | INFO | Logging level |
* ENABLE_AUTH defaults to False in .env.example. Always copy .env.example to .env to start with auth disabled.
Connecting an MCP Client
Point your MCP client at the server endpoint:
{
"mcpServers": {
"memory": {
"url": "http://localhost:5001/mcp"
}
}
}
See examples/fastmcp_client.py for a working client that stores and searches memories.
Development
make lint # ruff + mypy
make test # pytest with coverage
make pre-commit # run all pre-commit hooks
Documentation
| Guide | Description |
|---|---|
| Architecture | System diagrams, code structure, key components |
| Development | Setup, running locally, testing, code quality |
| Deployment | Podman, OpenShift, container configuration |
| Authentication | OAuth setup, auth modes, troubleshooting |
License
Apache 2.0 — derived from redhat-data-and-ai/template-mcp-server.