Skip to main content
Glama
README.md
<p align="center">
  <img src="docs/assets/og-image.png" alt="MCP Memory — memoria local para agentes IA vía MCP" width="720">
</p>

[English](README.en.md) · **Español**

# MCP Memory — Memoria local para agentes IA vía MCP

> **Lleva la memoria de tu agente IA a cualquier máquina.**
> Servidor MCP open source que da memoria persistente con búsqueda léxica (BM25) a Claude Desktop, Claude Code, OpenCode, Cursor, Continue y cualquier cliente compatible con [Model Context Protocol](https://modelcontextprotocol.io). SQLite + FTS5, **cero infra externa, 100% en tu hardware**.

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/MCP-stdio_%7C_Streamable_HTTP-green)](https://modelcontextprotocol.io)
[![Python](https://img.shields.io/badge/Python-3.11+-3776AB?logo=python&logoColor=white)](server/pyproject.toml)
[![CI](https://github.com/GermaniU/mcp-memory/actions/workflows/ci.yml/badge.svg)](https://github.com/GermaniU/mcp-memory/actions/workflows/ci.yml)
[![SQLite](https://img.shields.io/badge/Storage-SQLite%20%2B%20FTS5-003B57?logo=sqlite&logoColor=white)](server/src/mcp_memory/shared/store.py)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)

**Tags:** `mcp-server` · `ai-agents` · `sqlite` · `fts5` · `bm25` · `claude-code` · `cursor` · `opencode` · `lexical-search` · `agent-memory` · `local-first` · `self-hosted`

<p align="center">
  <img src="docs/assets/demo.gif" alt="El agente guarda un recuerdo en una sesión y lo recupera en otra" width="780">
</p>

<p align="center"><sub>El agente guarda algo en una sesión y lo recuerda en otra — mismo archivo SQLite, proceso nuevo. Sin nube, sin vectores, sin servicios extra.</sub></p>

---

## 💡 Por qué existe

Los agentes IA olvidan todo entre conversaciones. Las soluciones existentes son cloud-only, multi-tenant pesado, o están atadas a un único cliente. **MCP Memory** resuelve esto con tres ideas simples:

1. **Tu memoria, tu máquina.** Un solo archivo SQLite local. Cero datos en la nube, cero servicios externos que levantar.
2. **Conectas una vez, funciona en todos lados.** Es un servidor MCP estándar — cualquier cliente que hable MCP lo usa sin custom code.
3. **Cero overhead.** `pip install` y tienes 9 tools listas para tu agente en segundos — sin Docker, sin modelos que descargar.

---

## ⚡ Quickstart

Hay dos formas de correrlo. Elige una:

| Modo | Cuándo | Cómo arranca |
|------|--------|--------------|
| **stdio** | Claude Desktop, Claude Code, Cursor… (lo más simple) | El cliente lanza el proceso él solo. No hay server de fondo ni puerto. |
| **HTTP** | Varios clientes contra un mismo server, Docker, clientes web | Lo arrancas tú y queda escuchando en `http://localhost:8765/mcp`. |

### Opción A — stdio (sin dejar nada corriendo)

Con [`uv`](https://docs.astral.sh/uv/) instalado no hace falta clonar: el cliente descarga y lanza el server en cada sesión. Para Claude Code:

```bash
claude mcp add -s user mcp-memory -- uvx --from "git+https://github.com/GermaniU/mcp-memory#subdirectory=server" mcp-memory --stdio
```

Para Claude Desktop, Cursor y el resto, la config JSON está en [`docs/CLIENTS.md`](docs/CLIENTS.md#modo-stdio-recomendado). Todos los procesos comparten el mismo archivo SQLite (`DB_PATH`), así que la memoria es la misma en todos tus clientes.

### Opción B — HTTP (server de fondo)

```bash
git clone https://github.com/GermaniU/mcp-memory.git
cd mcp-memory/server
pip install -e .
mcp-memory
```

> Alternativa sin instalar en tu entorno global: `uvx --from . mcp-memory` (corriendo dentro de `server/`).

No hay pre-requisitos: nada que levantar, nada que descargar. Al arrancar, el server crea el archivo SQLite (`DB_PATH`, default `~/.agent-memory/memory.db`) y su schema (tabla `memories` + índice FTS5) si no existen.

Endpoint MCP: `http://localhost:8765/mcp`. Pégalo en la config de tu cliente (ver [`docs/CLIENTS.md`](docs/CLIENTS.md) — Claude Code, OpenCode, Cursor, Continue).

> `mcp-memory --stdio` (o `MCP_TRANSPORT=stdio`) arranca el modo stdio con la instalación local.

### 🔍 Diagnóstico y Chequeo de Salud

Verifica que tu Python tiene FTS5 compilado y que `DB_PATH` es accesible al instante:

```bash
mcp-memory check
```

`mcp-memory --help` lista los comandos y variables de entorno; `mcp-memory --version` imprime la versión instalada.

---

## 🛠 Tools MCP expuestas

| Tool             | Tipo | Para qué |
|------------------|------|----------|
| `memory_save`    | ✏️ escritura | Guardar texto + tags + metadata. |
| `memory_search`  | 👁 lectura | Búsqueda léxica (BM25 vía SQLite FTS5) con filtro por namespace. |
| `memory_update`  | ⚠️ destructiva | Cambiar contenido/tags/metadata por id. Re-sincroniza el índice FTS5 si cambia el contenido. Rechaza `content` vacío. |
| `memory_delete`  | ⚠️ destructiva | Borrar por id. |
| `memory_list`    | 👁 lectura | Paginado por namespace. |
| `memory_recent`  | 👁 lectura | Las últimas N por `updated_at`. |
| `memory_stats`   | 👁 lectura | Conteo, namespaces, oldest/newest. |
| `memory_export`  | 👁 lectura | Exporta todas las memorias (o las de un namespace) como JSONL. Devuelve `count` y el string `jsonl`. |
| `memory_import`  | ✏️ escritura | Importa un string JSONL producido por `memory_export`. Salta colisiones de id silenciosamente. Acepta `namespace_override` opcional. |

El **Tipo** se publica como [anotaciones MCP](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-annotations) (`readOnlyHint`, `destructiveHint`): los clientes que las soportan pueden auto-aprobar las lecturas y pedir confirmación antes de modificar o borrar. Al conectarse, el server también envía `instructions` al agente (cuándo buscar, cuándo guardar, cómo formular queries léxicas).

Schemas + ejemplos de invocación en [`docs/CLIENTS.md`](docs/CLIENTS.md).

---

## 🎯 Alcance actual

MCP Memory es deliberadamente pequeño. Hace **una cosa bien: memoria léxica de texto plano**. No es un sistema de RAG completo, no es un knowledge base, no es un grafo.

### Lo que SÍ hace
- ✅ Almacena y recupera **texto puro** en SQLite.
- ✅ Búsqueda léxica (BM25/FTS5) con filtro por `namespace`.
- ✅ Tags + metadata libres en cada entrada.
- ✅ 9 tools MCP estándar para cualquier agente compatible.
- ✅ Persistencia en disco (un único archivo `.db`), backup = copiar el archivo.

### Lo que NO hace (todavía)
- ❌ **No hace búsqueda semántica.** Es léxica (BM25): coincide términos, no significado — sinónimos o paráfrasis sin overlap de vocabulario no matchean.
- ❌ **No soporta imágenes ni gráficas.** Solo texto.
- ❌ **No soporta PDFs ni archivos binarios** — extrae el texto antes de guardarlo.
- ❌ **No es multi-tenant.** Una persona, una máquina, una memoria (con namespaces para separar contextos).
- ❌ **No tiene UI propia.** Lo administras desde el agente o por curl/MCP.
- ❌ **No sincroniza entre máquinas.** Backup manual (copiar el archivo `.db`) si quieres mover datos.
- ❌ **No tiene auth.** En modo HTTP solo escucha en `localhost` y con CORS cerrado (en stdio no abre ningún puerto). Si lo expones a internet, pon un proxy con auth. Ver [`SECURITY.md`](SECURITY.md).

Si necesitas algo de la lista NO, abre un [issue](https://github.com/GermaniU/mcp-memory/issues) con caso de uso real (no especulativo) — vamos por demanda, no por especulación.

---

## 🧭 ¿Y el `server-memory` oficial?

El MCP oficial incluye [`server-memory`](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) (`@modelcontextprotocol/server-memory`). No compiten por el mismo trabajo: ese es un **grafo de conocimiento**; este es **memoria léxica de texto**. Elige según lo que necesites recordar.

| | **MCP Memory** (este) | **`server-memory`** (oficial) |
|---|---|---|
| Modelo de datos | Entradas de texto planas (`content` + `tags` + `metadata`) | Grafo: entidades + relaciones + observaciones |
| Almacenamiento | Un archivo **SQLite** con índice **FTS5** | Un archivo **JSONL** con el grafo completo |
| Búsqueda | **BM25 con ranking** (FTS5), filtrada por `namespace` | `search_nodes`: match por *substring* en nombre/tipo/observaciones, **sin ranking** |
| Namespaces | ✅ un pool por proyecto o agente | ❌ |
| Tags / metadata libres | ✅ por entrada | ❌ |
| Export / import | ✅ `memory_export` / `memory_import` (JSONL) | ❌ hay que leer y escribir el archivo |
| Transporte | **stdio + Streamable HTTP** | stdio |
| Coste de leer | Ranking en SQLite: traes solo los hits | `read_graph` devuelve el grafo entero |

**En una frase:**
- Si tu problema son **hechos con relaciones** («Ana *trabaja_en* Acme», «*padre_de*…»), usa el grafo oficial.
- Si tu problema es **recordar notas y decisiones y encontrarlas por palabra clave**, separadas por proyecto y con export/import, usa MCP Memory.

No es «mejor que»: es **otra herramienta para otro trabajo** — y la que no te obliga a cargar el grafo completo en cada consulta.

---

## 🔌 Conectar tu cliente

Configuración lista para copiar en [`docs/CLIENTS.md`](docs/CLIENTS.md) (stdio y HTTP):

- 🟫 **Claude Desktop** — `claude_desktop_config.json` con `"command": "uvx"` (stdio).
- 🟦 **Claude Code** — `claude mcp add -s user mcp-memory -- uvx --from "git+https://github.com/GermaniU/mcp-memory#subdirectory=server" mcp-memory --stdio`, o por HTTP `claude mcp add -s user -t http mcp-memory http://localhost:8765/mcp` (las tools aparecen en sesiones nuevas).
- 🟧 **Cursor** — Settings → MCP Servers → Add new MCP Server.
- 🟩 **Continue** (VS Code / JetBrains) — `~/.continue/config.json`.
- 🟪 **OpenCode** — `~/.config/opencode/config.json`.

Snippets JSON listos en [`examples/`](examples/).

---

## 🧪 Smoke test con curl

Para validar el stack sin necesidad de un cliente MCP:

```bash
SESSION=$(curl -sS -D - -o /dev/null -X POST http://localhost:8765/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-06-18' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0.1"}}}' \
  | tr -d '\r' | awk '/^mcp-session-id:/{print $2}')

curl -sS -X POST http://localhost:8765/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-06-18' \
  -H "mcp-session-id: $SESSION" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'

curl -sS -X POST http://localhost:8765/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-06-18' \
  -H "mcp-session-id: $SESSION" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"memory_save","arguments":{"content":"funciona end-to-end","namespace":"smoke","tags":["ok"]}}}'
```

---

## 🧱 Arquitectura (vertical slice)

```
┌─ tu agente (Claude Code / OpenCode / Cursor / …) ─┐
│           │ MCP streamable HTTP                    │
│           ▼                                        │
│    localhost:8765/mcp                              │
└────────────┬───────────────────────────────────────┘
             │
   ┌─────────▼────────┐
   │   mcp-memory     │
   │   (Python+MCP)   │
   └─────────┬────────┘
             │
             ▼
   ┌──────────────────────────┐
   │  SQLite (archivo local)  │  ← memories + memories_fts (FTS5/BM25)
   └──────────────────────────┘
```

Cada tool MCP vive en su propia carpeta (`server/src/mcp_memory/tools/<tool>/handler.py`). Añadir una tool nueva = añadir una carpeta + un decorator en `server.py`. Cero acoplamiento.

Detalle técnico en [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).

---

## 🤝 Contribuye

MCP Memory es **un regalo a la comunidad** — MIT, sin trampas. PRs, issues y forks bienvenidos.

**Reglas (resumen):**
1. **Clean Code · SOLID · KISS · YAGNI · Vertical slice · Tests primero.** No se aceptan PRs sin tests para la lógica nueva.
2. **Identifiers en inglés**, comentarios y commits en español. Conventional Commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`).
3. **Una tool nueva = una carpeta nueva.** No tocar slices existentes salvo bug.
4. **DIP**: dependencias externas detrás de un `Protocol` para que el test no necesite servicios externos.
5. **Sin abstracciones especulativas.** Si solo hay 1 implementación, no hay interfaz.
6. **Documenta el WHY, no el WHAT.** El nombre de la función ya cuenta el qué.

Detalle completo + workflow paso a paso en [`CONTRIBUTING.md`](CONTRIBUTING.md).

```bash
# Setup local de desarrollo
cd server
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest tests/unit -q          # 81 unit tests, ~1s
pytest tests/integration -q   # 17 tests E2E reales contra SQLite/FTS5 (incluye stdio), sin servicios externos
ruff check src tests scripts
```

---

## 🩹 Troubleshooting (errores reales que ya pisé)

**`no such module: fts5` al arrancar**
- Tu Python no tiene FTS5 compilado en su módulo `sqlite3` (típico en algunos builds de Linux). Usa el Python de Homebrew/python.org (macOS/Windows) o instala `libsqlite3-dev` antes de compilar Python (Linux, pyenv/asdf). Verifica con `mcp-memory check`.

**`Connection reset by peer` al hacer `curl http://localhost:8765/mcp`**
- Falta el header `Accept: application/json, text/event-stream`. Sin él, FastMCP cierra la conexión.

**`memory_search` devuelve vacío**
- ¿Mismo namespace? Si guardaste sin namespace, busca con `default`. Recordá que la búsqueda es léxica (BM25): la query necesita compartir términos con el contenido guardado, no solo el significado.

**`mcp-memory` no arranca / error de permisos en `DB_PATH`**
- El directorio padre de `DB_PATH` no es escribible. `mcp-memory check` valida esto explícitamente antes de fallar en caliente.

**Quiero mover mi memoria a otra máquina**
- Copia el archivo de `DB_PATH` (default `~/.agent-memory/memory.db`) — es autocontenido, no hay estado adicional que migrar.

---

## 📚 Documentación

- [`docs/INSTALL.md`](docs/INSTALL.md) — instalación detallada, variables, troubleshooting extendido.
- [`docs/CLIENTS.md`](docs/CLIENTS.md) — config para Claude Code, OpenCode, Cursor, Continue.
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — decisiones técnicas y por qué.
- [`SECURITY.md`](SECURITY.md) — modelo de amenazas y cómo reportar vulnerabilidades.
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — disciplinas, workflow, cómo añadir una tool.
- [`CHANGELOG.md`](CHANGELOG.md) — historial de cambios.

---

## 📄 Licencia

[MIT](LICENSE) — úsalo, fórkalo, regálale a otra gente más memoria local.

---

**Hecho por [@GermaniU](https://github.com/GermaniU)** con disciplinas de software profesional. Si te ha servido, una ⭐ ayuda a que más gente lo encuentre. Si te ha roto algo, abre un issue y lo arreglamos.

Maintenance

ActivityMaintained
ResponsivenessNo issues