The Problem

Agents often lose context between sessions, leading to repetitive explanations and missed opportunities. A shared, structured memory store that automatically links related facts can keep agents consistent and efficient.

What This Does

Forgetful is an MCP (Model Context Protocol) server built on FastMCP. Clients send memories—atomic notes with title, content, tags, and context—via the REST API in app/routes/api/memories.py. The service creates embeddings (app/repositories/embeddings/embedding_adapter.py), stores them in a relational database (postgres or sqlite adapters under app/repositories/postgres/ and app/repositories/sqlite/), and auto‑links similar memories (app/services/memory_service.py). The graph is exposed through app/routes/api/graph.py and kept in app/models/graph_models.py.

How It Is Wired

Entry point – main.py launches a FastMCP app.

from fastmcp import FastMCP
app = FastMCP()

Routing – API routes are registered in app/routes/api/__init__.py, which imports endpoint modules. Service layer – Each endpoint calls a service function, e.g., app/routes/api/memories.py calls app/services/memory_service.create_memory(). Repository layer – Service functions delegate persistence to a repository chosen by database dialect; e.g., app/services/memory_service.create_memory() calls app/repositories/postgres/memory_repository.insert(). Models – SQLAlchemy models in app/models/memory_models.py map to the tables defined in app/repositories/postgres/postgres_tables.py. Embeddings – embedding_adapter.py uses FastEmbed to generate vectors, then stores them via the same repository. Graph linking – After insertion, memory_service.link_similar() queries the vector index and creates entries in graph_models linking memories with a similarity score.

The flow touches the database once per create, twice for linking, and once per read. The repository layer is the widest blast radius; any change here affects all services.

How To Use It

Setup – Build the container image:

git clone https://github.com/moses-y/forgetful
cd forgetful
docker build -t forgetful .

Configuration – Copy the example env file and set credentials:

cp docker/.env.example .env
# edit .env to set POSTGRES_PASSWORD, etc.

Running – Spin the stack:

docker compose -f docker/docker-compose.yml up

The FastMCP server listens on http://localhost:8000. Alternatively, run the Python entry point directly (dev mode):

uvicorn main:app --reload

Real-World Use

A coding agent can store a new function snippet as a memory:

curl -X POST http://localhost:8000/api/memories \
  -H "Content-Type: application/json" \
  -d '{"title":"Quicksort","content":"def quicksort(arr): ...","tags":["algorithm"],"context":"Refactor project"}'

Later, the agent can query for “sorting algorithms” and receive the linked snippet, its provenance, and related documents.

Code Health & Issues

  • Low – Dependencies declared without a lockfile (pyproject.toml only). File: pyproject.toml
  • Low – No reproducible build due to missing lockfile. File: pyproject.toml

The repository contains tests (≈145), CI workflows (.github/workflows/*.yml), and documentation. Licensing is present (LICENCE.md). No obvious security or documentation gaps.

The Bottom Line

Forgetful provides a pragmatic, MCP‑based memory store that auto‑links facts and supports multiple backends. Its FastMCP foundation gives a clean API, while the repository pattern isolates persistence. The lack of a lockfile limits reproducibility, but otherwise the code is well‑structured for agents that need a shared, schema‑driven knowledge base. Ideal for teams building agent workflows that require consistent context and semantic search.