MeMCP
by haitham72
README.md
# MeMCP

**Local temporal memory for AI agents, served over MCP.**
[](https://github.com/haitham72/MeMCP/actions/workflows/ci.yml) [](LICENSE) [](pyproject.toml) [](https://modelcontextprotocol.io)
## Why
Agents forget everything between sessions, and plain vector memory cannot answer "who managed whom, as of when" or "has this kind of slip happened before". MeMCP keeps a dated timeline in markdown you own, indexes it on your machine, and exposes it to any MCP client.
## Features
- Markdown vault is the source of truth; Postgres, BM25 and Chroma are rebuildable indexes.
- Hybrid search (semantic + lexical + entity + severity, fused with RRF) over events, threads and transcripts.
- Entities with aliases and relationships that have validity dates (`manages` until a date).
- Patterns and advice with check-in dates and confidence decay: "what is overdue?"
- Approval-gated writes: `memory_draft` -> your approval -> `memory_commit` -> `memory_sync`.
- Optional code graph (symbols and call edges) over your own repo.
- Fully local: local Postgres, local embeddings, no hosted service. 45 tools over stdio.
## Quickstart
Requires Docker, [uv](https://docs.astral.sh/uv/) and Python 3.11 (uv fetches it).
```sh
git clone https://github.com/haitham72/MeMCP && cd MeMCP
uv tool install . --python 3.11
export PGPASSWORD=choose-a-password # PowerShell: $env:PGPASSWORD="choose-a-password"
docker compose up -d db
memcp sync --vault examples/sample_vault
memcp doctor
```
That loads the synthetic "Fjord Labs" vault (a slipping launch, a vendor outage, a pricing reversal, a manager handover, an overdue advice item). The compose file maps Postgres to host port 5433; set `PGPORT` if you change it. The first search downloads a small embedding model; `MODEL_TIER=S` keeps it light, and a TF-IDF fallback works fully offline.
To use your own vault, run `memcp init` in the project where your agent works. It scaffolds `./memory`, a `.env` and the client config.
## Connect a client
Use an absolute vault path. `PGPASSWORD` must be visible to the server process.
Claude Code:
```sh
claude mcp add memcp -e PGPASSWORD=$PGPASSWORD -- memcp serve --vault /abs/path/to/examples/sample_vault
```
Claude Desktop (`claude_desktop_config.json`) and Cursor (`.cursor/mcp.json`) use the same shape:
```json
{
"mcpServers": {
"memcp": {
"command": "memcp",
"args": ["serve", "--vault", "/abs/path/to/examples/sample_vault"],
"env": { "PGPASSWORD": "choose-a-password" }
}
}
}
```
`memcp init --client claude-code|cursor|codex` writes this for you.
## Example session
A real stdio MCP session against the synced sample vault, driven by a short script (no LLM in the loop). Output is verbatim, only the JSON-RPC framing is summarised.
```text
initialize -> serverInfo: {"name": "memcp", "version": "0.1.0"}
tools/list -> 45 tools
>>> tools/call pg_advice_due {"days": 7}
=== Advice Entries Due / Past Due ===
Distrust the first vendor status update (vendor_outage) — check-in: 2026-07-05, confidence: 0.80, status: pending
Re-lock scope after every addition (launch_delay) — check-in: 2026-04-01, confidence: 5.20, status: active
Run the failover drill monthly (vendor_outage) — check-in: 2026-10-03, confidence: 6.65, status: active
>>> tools/call pg_hybrid_search {"query": "launch slip after scope sign-off", "limit": 3}
=== Hybrid Search (RRF): 'launch slip after scope sign-off' ===
1. [rrf=0.016393] Scope creep after sign-off / launch_delay/high (2026-03-10)
signals: semantic#1 lexical- entity- severity-
Three features land after the freeze despite the January promise. Classic P1: scope creep after sign-off, see [[pricing_change]] for the pricing fallout.
2. [rrf=0.015885] Launch delayed to September / launch_delay/high (2026-05-19)
signals: semantic#4 lexical- entity- severity#5
Official: the launch is delayed to September. The two-week slip from February never got recovered.
3. [rrf=0.015385] Launch slips two weeks / launch_delay/medium (2026-02-20)
signals: semantic#5 lexical- entity- severity-
The launch slips two weeks after the migration runs long. Any further delay pushes us into the pricing review window.
>>> tools/call get_pattern {"name": "P1"}
## P1 — Scope creep after sign-off
**Entity:** `Tomas`
**Verdict:** Tomas agrees to post-freeze additions to avoid conflict, then pays for them in schedule slips.
Commitments made at sign-off decay within weeks unless Alex re-locks them.
**Confidence:** High
**Status:** Active
**Links:** [P3]
--- Linked pattern (P3) ---
## P3 — Decision by silence
**Entity:** `Alex Morgan`
**Verdict:** Unanswered proposals are decided by whoever acts first, not by Alex. Silence reads as consent.
**Confidence:** Medium
**Status:** Active
**Links:** [P1]
>>> tools/call relationship_chart {}
=== Relationship Chart (manages, from entity_relationships) ===
Tomas
└ Dana
└ Marcus
```
## Architecture
```mermaid
flowchart LR
MD[Markdown vault] --> SYNC[memcp sync]
SYNC --> PG[(Postgres + pgvector)]
SYNC --> BM25[BM25]
SYNC --> CHROMA[Chroma]
PG --> MCP[MCP server]
BM25 --> MCP
CHROMA --> MCP
MCP --> AGENT[Agent]
AGENT -- draft, approve, commit --> MD
```
1. Markdown is the source of truth. Delete the database and rebuild it from the vault.
2. Nothing leaves your machine.
3. The agent asks before it writes.
## Tools
45 tools in five families ([full reference](docs/tools.md)):
| Family | Examples |
|---|---|
| Remember | `memory_extract`, `memory_draft`, `memory_commit`, `memory_sync`, `advice_add` |
| Recall | `memory_context`, `pg_hybrid_search`, `pg_search_all`, `pg_timeline`, `search_threads` |
| Connect | `pg_entity_card`, `relationship_chart`, `relationship_path`, `check_aliases`, `pg_traverse` |
| Reflect | `get_pattern`, `pg_advice_due`, `memory_salience`, `memory_conflicts`, `reflect` |
| Code | `code_symbol`, `code_search`, `code_graph`, `workspace_map` |
## Configuration
All settings are environment variables (or a `.env`); see [docs/configuration.md](docs/configuration.md).
| Variable | Default | Purpose |
|---|---|---|
| `MEMCP_VAULT` | `memory` | Vault directory |
| `MEMCP_OWNER` | empty | Owner entity (`me`/`my` resolve to it) |
| `PGHOST` / `PGPORT` | `localhost` / `5433` | Postgres location |
| `PGDATABASE` / `PGUSER` | `memcp` / `memcp` | Postgres database and user |
| `PGPASSWORD` | none | Postgres password (required) |
| `MEMCP_PG_DSN` | empty | Full DSN, overrides the `PG*` parts |
| `MODEL_TIER` | `M` | Embedding model: `S` small, `M`/`L` nomic with fallbacks |
## Development
```sh
uv venv --python 3.11 && uv pip install -e ".[dev]"
export PGPASSWORD=memcp MEMCP_TEST_DSN=postgresql://memcp:memcp@localhost:5433/memcp_test
python -m pytest tests/ -q
```
Tests that need Postgres are skipped when it is unreachable. CI runs the full suite against `pgvector/pgvector:pg16`. See [CONTRIBUTING.md](CONTRIBUTING.md), [docs/troubleshooting.md](docs/troubleshooting.md) and [docs/comparison.md](docs/comparison.md) (an honest comparison with mem0, Zep/Graphiti, Letta and basic-memory).
## License
MIT. See [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues