Content
# Memory MCP Server
A personal long-term memory system for AI assistants (Claude, Copilot CLI, etc.) that stores, retrieves, and manages contextual memories using local semantic search, a temporal knowledge graph, and source-aware composite ranking.
No external API keys, no Docker, no cloud services. Everything runs locally.
## Features
- **Semantic search**: Vector similarity via sentence-transformers (all-MiniLM-L6-v2) and LanceDB
- **Composite ranking**: Scores combine similarity, recency, importance, access frequency, and source reliability
- **Source-aware scoring**: First-hand observations (from conversations) are boosted over bulk-imported data, preventing stale imports from drowning out current facts
- **Knowledge graph**: SQLite-backed temporal fact store with entity-relationship triples, time validity windows, and point-in-time queries
- **Smart context injection**: Token-budget-aware retrieval with modes (coding, chat, quick, project) for optimal context loading
- **Session briefing**: Pre-baked context served instantly at session start with recent conversation digests, key memories, and KG facts; no embedding latency
- **Conversation ingestion**: Auto-indexes Copilot CLI sessions via filesystem watcher for cross-session search
- **Memory lifecycle**: Pin, archive, forget, and consolidate memories; directive memories force-load at every session
- **Persistent HTTP server**: Runs as a Windows scheduled task with supervisor, watchdog, and sleep/wake resilience
## Architecture
```
server.py MCP server (stdio or HTTP transport)
├── memory_store.py LanceDB vector storage (memories + conversations)
├── embeddings.py Local sentence-transformers, LRU cache, background preload
├── ranking.py Composite scoring with source boost
├── knowledge_graph.py SQLite temporal fact store (entity/predicate/object triples)
├── briefing.py Pre-baked session context generator (zero-latency startup)
├── config.py Environment-based configuration
├── watcher.py Filesystem watcher for Copilot CLI session ingestion + briefing
├── server_service.py Windows Task Scheduler service (install/start/stop)
└── service.py Watcher scheduled task service
```
## Quick Start
```bash
# Create virtual environment
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # Linux/macOS
# Install dependencies
pip install -r requirements.txt
# Run via stdio (for MCP client integration)
python server.py
# Run as persistent HTTP server
python server.py --http --port 5123
```
### Persistent Background Service (Windows)
```bash
# Install as a Windows scheduled task with auto-restart
python server_service.py install
python server_service.py start
# Check status
python server_service.py status
# Stop/restart
python server_service.py stop
python server_service.py start
```
Resilience layers:
1. **Supervised mode**: Inner restart loop for transient Python crashes
2. **Repetition trigger**: Task Scheduler re-launches every 2 minutes if not running
3. **Resume trigger**: Restarts on wake from sleep/hibernate
4. **Watchdog**: Health-checks every 5 minutes, force-restarts if hung
## MCP Tools (22 total)
### Memory Management
| Tool | Description |
|------|-------------|
| `memory_store` | Store a new memory with category, importance, tags, and source |
| `memory_search` | Semantic search with composite ranking |
| `memory_list_recent` | List memories by creation time |
| `memory_pin` / `memory_unpin` | Pin memories so they always surface when relevant |
| `memory_forget` | Permanently delete a memory |
| `memory_stats` | Collection statistics (counts by category, source, pinned/archived) |
| `memory_context` | Token-budget-aware context blob for session start (modes: coding, chat, quick, project) |
| `memory_refresh_briefing` | Manually regenerate the session briefing |
| `memory_consolidate` | Find and merge near-duplicate memory clusters |
### Knowledge Graph
| Tool | Description |
|------|-------------|
| `memory_kg_add` | Store entity-relationship-object triples with time validity |
| `memory_kg_query` | Query facts about an entity (supports point-in-time queries) |
| `memory_kg_invalidate` | Soft-expire facts (preserves history, excludes from current queries) |
| `memory_kg_timeline` | Chronological history of an entity showing all changes |
| `memory_kg_stats` | Graph statistics (entities, relationships, active/expired counts) |
### Conversation Search
| Tool | Description |
|------|-------------|
| `conversation_search` | Semantic search across ingested Copilot CLI sessions |
| `conversation_get_session` | Retrieve full conversation for a specific session |
| `conversation_stats` | Ingestion statistics (turns, sessions, date range) |
## Ranking System
Search results are scored using a weighted composite of five signals:
| Signal | Default Weight | Description |
|--------|---------------|-------------|
| Similarity | 0.55 | Cosine similarity from vector search |
| Recency | 0.20 | Exponential decay (30-day half-life) |
| Importance | 0.15 | User-assigned 1-10 scale |
| Frequency | 0.10 | Log-scaled access count with recency decay |
| **Source boost** | multiplier | `chat` = 1.10x, `import` = 0.90x, other = 1.0x |
The source boost is applied as a final multiplier on the composite score, ensuring that first-hand observations consistently outrank bulk-imported data when relevance is comparable.
Pinned memories bypass normal ranking and are included whenever they meet a minimum similarity threshold.
## Session Briefing
The session briefing provides zero-latency context injection at session start. Instead of running an embedding + vector search on every `memory_context()` call, the system pre-generates a compact `briefing.json` file in the background.
**How it works:**
1. The watcher ingests Copilot CLI sessions and stores session metadata (first user message, turn count, timestamps)
2. After each ingestion (and every 5 minutes), the briefing is regenerated from:
- Recent session digests (last 7 days, max 20 sessions) with session IDs for drill-down
- Key memories (pinned + high-importance)
- Active knowledge graph facts
3. When `memory_context()` is called without a topic, it serves the cached briefing instantly (file read, no ML)
4. When called with a topic, it falls back to dynamic embedding + search
**Staleness handling:**
- Mutating tools (store, pin, forget, KG add/invalidate) mark the briefing as stale via a marker file
- The watcher's periodic regeneration clears the stale marker and refreshes
- The `memory_refresh_briefing` tool can manually trigger regeneration
**Generating the briefing manually:**
```bash
python watcher.py --generate-briefing
```
## Configuration
All settings are configurable via environment variables:
| Variable | Default | Description |
|----------|---------|-------------|
| `EMBEDDING_MODEL` | `all-MiniLM-L6-v2` | Sentence-transformers model name |
| `EMBEDDING_DIMENSIONS` | `384` | Vector dimensions |
| `EMBEDDING_CACHE_SIZE` | `512` | LRU cache for embedding vectors |
| `WEIGHT_SIMILARITY` | `0.55` | Ranking weight for semantic similarity |
| `WEIGHT_RECENCY` | `0.20` | Ranking weight for recency |
| `WEIGHT_IMPORTANCE` | `0.15` | Ranking weight for importance |
| `WEIGHT_FREQUENCY` | `0.10` | Ranking weight for access frequency |
| `RECENCY_HALF_LIFE_DAYS` | `30.0` | Days until recency score decays to 0.5 |
| `SOURCE_BOOST_CHAT` | `1.10` | Score multiplier for conversation-sourced memories |
| `SOURCE_BOOST_IMPORT` | `0.90` | Score multiplier for bulk-imported memories |
| `SOURCE_BOOST_DEFAULT` | `1.0` | Score multiplier for other sources |
| `PIN_SIMILARITY_THRESHOLD` | `0.4` | Minimum similarity for pinned memory inclusion |
| `MEMORY_DATA_DIR` | (project dir) | Base directory for all data files |
| `COPILOT_SESSION_DIR` | `~/.copilot/session-state` | Copilot CLI session directory for ingestion |
| `BRIEFING_MAX_AGE_MINUTES` | `120` | Maximum age before briefing is considered stale |
| `BRIEFING_RECENT_DAYS` | `7` | How many days of sessions to include in briefing |
| `BRIEFING_MAX_SESSIONS` | `20` | Maximum number of recent sessions in briefing |
| `BRIEFING_REGEN_INTERVAL` | `5` | Minutes between periodic briefing regenerations |
## MCP Client Configuration
### Copilot CLI (GitHub Copilot)
Add to your MCP settings (e.g., `~/.config/github-copilot/mcp.json`):
```json
{
"servers": {
"memory": {
"url": "http://localhost:5123/mcp"
}
}
}
```
### Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"memory": {
"command": "python",
"args": ["path/to/server.py"]
}
}
}
```
## Data Storage
All data is local, file-based, and git-ignored:
- `lancedb_data/` : Vector database (memories + conversations)
- `knowledge_graph.db` : SQLite knowledge graph
- `ingestion_state.db` : Conversation watcher state
- `logs/` : Server and watchdog logs
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...