{
  "markdown": "<!-- mcp-name: io.github.simoneb79/memory-engine-mcp -->\n\n<p align=\"center\">\n  <a href=\"#\"><img alt=\"Version\" src=\"https://img.shields.io/badge/version-1.7.0-blue\" /></a>\n  <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/badge/license-MIT-green\" /></a>\n  <a href=\"#\"><img alt=\"Python\" src=\"https://img.shields.io/badge/python-3.12+-blue\" /></a>\n  <a href=\"server.json\"><img alt=\"MCP Registry Ready\" src=\"https://img.shields.io/badge/MCP%20Registry-ready-purple\" /></a>\n  <a href=\"Dockerfile\"><img alt=\"Docker\" src=\"https://img.shields.io/badge/docker-ready-2496ED\" /></a>\n</p>\n\n<p align=\"center\">\n  <img src=\"docs/logo.jpg\" width=\"128\" height=\"128\" alt=\"Memory Engine Logo\" />\n</p>\n\n<h1 align=\"center\">🧠 Memory Engine MCP</h1>\n\n<p align=\"center\">\n  <strong>Local-first, graph-aware long-term memory for AI assistants.</strong><br>\n  SQLite + semantic search + knowledge graph + MCP tools for agents that need continuity.\n</p>\n\n<p align=\"center\">\n  Works with Claude Desktop · Claude Code · Cursor · Cline · Windsurf · OpenClaw · any MCP client\n</p>\n\n---\n\n## Why Memory Engine?\n\nMost MCP memory servers are either simple key-value stores or plain text search wrappers.\n\nMemory Engine is different: it models memory as **typed atoms** connected by **typed bonds**, then retrieves context with a hybrid ranking pipeline that combines:\n\n- full-text search (SQLite FTS5)\n- semantic similarity via local Ollama embeddings\n- confidence, recency, and weight\n- graph expansion from related memories\n\nThe goal is not just storage. The goal is a memory system that can **recall, connect, decay, curate, and learn** over time.\n\n## Highlights\n\n- **Local-first** — SQLite database, optional local embeddings via Ollama, no required cloud API.\n- **MCP-native** — exposes 35 tools through FastMCP.\n- **Graph-aware recall** — expands top hits through bidirectional bonds for richer context.\n- **Semantic search** — meaning-based retrieval with `nomic-embed-text`.\n- **Markdown coexistence** — import existing notes one-way without replacing your human-readable memory.\n- **Error memory** — remembers mistakes and corrections, with auto-promotion to preferences after repeated failures.\n- **Cognitive curator** — non-destructive maintenance pass for compaction, bond suggestions, duplicate detection, and isolated atom classification.\n- **Session watcher** — canonical OpenClaw SQLite ingestion (schema 17), reset-aware digests, and JSONL legacy fallback.\n- **Backup & restore** — full SQLite snapshots, JSON export/import, verified restores with automatic safety backups.\n- **Auth & hardening** — optional API token, secure bind, input validation, rate limiting.\n- **Test suite** — 144 tests covering CRUD, ranking, migrations, auth, backup, concurrency, and transcript ingestion.\n- **Benchmark** — CLI recall quality suite with Precision@K, MRR, latency percentiles.\n\n## Architecture\n\n```text\nAI assistant / MCP client\n        │\n        ▼\nFastMCP server — 35 tools\n        │\n        ▼\nMemory engine — hybrid ranking, graph recall, decay, learning\n        │\n        ├── SQLite — atoms, bonds, FTS5, JSON metadata, versions\n        ├── Ollama — optional local embeddings\n        ├── Curator — conservative maintenance\n        └── Session watcher — OpenClaw SQLite + JSONL fallback\n```\n\n## MCP Tools\n\n### Memory\n\n| Tool | Purpose |\n|---|---|\n| `remember` | Create or update an atom |\n| `recall` | Smart hybrid recall with graph expansion |\n| `working_set` | Build a task-oriented context pack |\n| `semantic_search` | Pure semantic search |\n| `get_atom` | Read one atom with bonds |\n| `list_atoms` | Browse atoms by domain/type/status |\n| `merge_atoms` | Merge duplicate atoms |\n| `export_atom` | Export one atom as markdown |\n\n### Knowledge graph\n\n| Tool | Purpose |\n|---|---|\n| `link` / `unlink` | Create or remove typed bonds |\n| `search_graph` | Traverse the graph from one atom |\n| `suggest_bonds` | Suggest bonds for one atom |\n| `suggest_bonds_all` | Suggest or create bonds in bulk |\n\n### Learning and maintenance\n\n| Tool | Purpose |\n|---|---|\n| `curator_run` | Conservative curation pass |\n| `cognitive_status` | Graph and memory health metrics |\n| `learning_run` | Detect contradictions, weak atoms, merge candidates, gaps |\n| `ask_pending` / `answer_human` | Human-in-the-loop clarification |\n| `decay_run` | Run decay cycle |\n| `cleanup_sessions` | Remove expired session atoms |\n| `cleanup_duplicates` | Remove duplicate session atoms |\n| `reindex_embeddings` | Rebuild embeddings |\n\n### Error memory and preferences\n\n| Tool | Purpose |\n|---|---|\n| `error_check` | Check past failures before doing a task |\n| `error_log` | Record a mistake and the correction |\n| `error_list` | Browse unresolved/resolved errors |\n| `preference_search` | Search structured preferences |\n\n### Import and introspection\n\n| Tool | Purpose |\n|---|---|\n| `import_markdown` | Import markdown notes into atoms |\n| `memory_summary` | 3-level summary: global → domain → detail |\n| `stats` | Database statistics |\n| `version` | Server version |\n| `recall_session` | Search one OpenClaw session |\n| `session_summary` | Summarize one OpenClaw session |\n| `memory_contradict` | Supersede an old atom with a newer contradictory one |\n| `list_contradictions` | List explicit contradiction/supersession records |\n| `classify_memory_tier` | Infer the 3-tier class (episodic/semantic/procedural) |\n| `memory_impact` | Impact analysis: what depends on this atom |\n\n### Backup, restore & export\n\n| Tool | Purpose |\n|---|---|\n| `backup_database` | Create, list, verify, or clean up SQLite snapshots |\n| `restore_database` | Restore from a backup (with automatic safety backup) |\n| `export_all` | Export all memory data as portable JSON |\n| `import_data` | Import from JSON (merge or replace mode) |\n\n## Web UI (optional)\n\nMemory Engine includes an optional web UI for graph exploration, atom\ninspection, contradiction browsing, and impact analysis.\n\n```bash\n# In docker-compose.yml, add:\n#   environment:\n#     - MEM_UI_PORT=6000\n#   expose:\n#     - \"6000\"\n```\n\nOr run standalone:\n\n```bash\npython3 web_ui.py\n# Open http://localhost:6000\n```\n\n<p align=\"center\">\n  <img src=\"docs/graph-ui-screenshot.png\" alt=\"Memory Engine Web UI — graph explorer\" width=\"800\" />\n  <br>\n  <em>Web UI: interactive graph, atom details, contradiction browser, stats dashboard</em>\n</p>\n\n## Quick start with Docker\n\n### Option A — Use the pre-built image (recommended)\n\n```yaml\n# docker-compose.yml\nservices:\n  memory-engine:\n    image: ghcr.io/simoneb79/memory-engine-mcp:1.7.0\n    ports:\n      - \"8085:8085\"\n    volumes:\n      - memory-data:/data\n    restart: unless-stopped\n\nvolumes:\n  memory-data:\n```\n\n```bash\ndocker compose up -d\n```\n\n> **Pin the version.** Use an explicit tag like `:1.7.0` in production.\n> Avoid `:latest` — it can change without notice.\n\n### Option B — Build from source\n\n```bash\ngit clone https://github.com/SimoneB79/memory-engine-mcp.git\ncd memory-engine-mcp\ncp docker-compose.yml docker-compose.local.yml\n# Edit volume paths in docker-compose.local.yml if needed\ndocker compose -f docker-compose.local.yml up -d --build\n```\n\nDefault endpoint:\n\n```text\nhttp://localhost:8085/sse\n```\n\nExample MCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"memory-engine\": {\n      \"url\": \"http://localhost:8085/sse\",\n      \"transport\": \"sse\"\n    }\n  }\n}\n```\n\nSee [`docs/INSTALL.md`](docs/INSTALL.md) for Docker, local Python, Claude Desktop, Cursor, and OpenClaw examples.\n\n## Local Python\n\n```bash\npython -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\npython server.py\n```\n\n## Configuration\n\nMain configuration file: [`config.json`](config.json)\n\nImportant environment variables:\n\n| Variable | Default | Purpose |\n|---|---:|---|\n| `MEMORY_DB_PATH` | `/data/memory.db` | SQLite database path |\n| `MARKDOWN_SOURCE` | `/workspace/memory` | Markdown directory for import |\n| `MEMORY_HOST` | `127.0.0.1` | Server bind address (secure default) |\n| `MEMORY_PORT` | `8085` | SSE port |\n| `MEMORY_API_TOKEN` | _(none)_ | Optional API token for auth (see Security) |\n| `OPENCLAW_AGENT_DB` | _(none)_ | Preferred per-agent OpenClaw SQLite DB (schema 17) |\n| `OPENCLAW_SESSIONS_DIR` | `/sessions` | Legacy JSONL fallback when no agent DB is configured |\n| `SESSION_DIGEST_DIR` | `/data/session_digests` | Optional session digest output |\n\nFor the SQLite mount, WAL/SHM handling, filtering, and security boundary, see\n[OpenClaw transcript ingestion](OPENCLAW_TRANSCRIPTS.md).\n\nSemantic search requires Ollama reachable from the container or host. Default:\n\n```json\n{\n  \"ollama\": {\n    \"enabled\": true,\n    \"host\": \"http://ollama:11434\",\n    \"model\": \"nomic-embed-text\"\n  }\n}\n```\n\nIf you do not use Ollama, set `ollama.enabled` to `false`; FTS recall still works.\n\n## Memory model\n\nAtoms have:\n\n- `title`\n- `body`\n- `type`: `fact`, `decision`, `event`, `preference`, `log`, `procedure`, `note`, etc.\n- `domain`: project or topic namespace\n- `confidence`\n- `weight`\n- `tags`\n- optional TTL\n\nBonds connect atoms with relation types:\n\n```text\nis_a · part_of · depends_on · contradicts · refines · derived_from · detail_of · related_to\n```\n\n## Example usage\n\n```python\nremember(\n    title=\"Use PostgreSQL for analytics\",\n    body=\"SQLite is kept for local memory, PostgreSQL is used for multi-user analytics.\",\n    type=\"decision\",\n    domain=\"project:analytics\",\n    confidence=0.9,\n    tags=[\"database\", \"architecture\"]\n)\n```\n\n```python\nrecall(query=\"what database did we choose for analytics?\", limit=5)\n```\n\n```python\nworking_set(\n    query=\"continue the analytics backend work\",\n    domain=\"project:analytics\",\n    limit=8,\n    graph_depth=1\n)\n```\n\n## Security\n\nBy default, Memory Engine runs in **open mode** (no auth) — safe for stdio\nor trusted local environments.\n\nTo enable API token auth:\n\n```json\n// config.json\n{\n  \"security\": {\n    \"api_token\": \"your-secret-token\",\n    \"allow_remote\": false\n  }\n}\n```\n\nOr via environment variable:\n\n```bash\nMEMORY_API_TOKEN=your-secret-token\n```\n\nWhen auth is enabled:\n- MCP SSE requests must include `Authorization: Bearer <token>`\n- Web UI API endpoints require `?token=<token>` or Bearer header\n- Server binds to `127.0.0.1` unless `allow_remote: true`\n- Input validation (title/body size limits) and rate limiting are always active\n\nSee [`CHANGELOG.md`](CHANGELOG.md) for the full list of security features.\n\n## Publishing and registries\n\nThis repository is prepared for MCP discovery:\n\n- MCP Registry name: `io.github.simoneb79/memory-engine-mcp`\n- Registry metadata: [`server.json`](server.json)\n- Docker/OCI verification label: included in [`Dockerfile`](Dockerfile)\n- Client config example: [`mcp.json`](mcp.json)\n\nSee [`docs/PUBLISHING.md`](docs/PUBLISHING.md) for the publication checklist.\n\n## Repository status\n\n- Public GitHub repository: https://github.com/SimoneB79/memory-engine-mcp\n- Existing listing: https://mcpmarket.com/server/memory-engine\n- License: MIT\n\n## License\n\nMIT — see [`LICENSE`](LICENSE).\n\n---\n\n<p align=\"center\">\n  Made with 🧠 by <a href=\"https://github.com/SimoneB79\">SimoneB79</a>\n</p>\n",
  "bytes": 11051,
  "sha": "1d9556de92167ece42c91c968742ba996fa1f06ecd99593c76f45fa12012c6f6",
  "repo_slug": "simoneb79/memory-engine-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_simoneb79_memory_engine_mcp_cefc4321/readme"
}