Skip to main content

Self-hosted semantic memory layer for AI tools. MCP-native, privacy-first, hybrid search.

Project description

Engram — Personal Semantic Memory for AI

A self-hosted semantic memory layer that gives any AI tool persistent, searchable recall.

PyPI Python 3.12+ Django 5 PostgreSQL + pgvector MCP Compatible License: MIT


What is Engram?

Engram is a personal knowledge base that stores your notes, conversations, documents, and web pages as vector embeddings — then lets any MCP-compatible AI assistant (Claude, Cursor, Windsurf, etc.) search and recall them by meaning, not just keywords. Everything lives in a PostgreSQL database you control, runs locally or in the cloud, and costs near-zero to self-host.

Features

  • Hybrid Search — Combines vector similarity (pgvector HNSW) with PostgreSQL full-text BM25, fused via Reciprocal Rank Fusion
  • MCP Server — Any MCP-compatible client can store, search, and manage memories over HTTP
  • REST API — Full CRUD + search, with OpenAPI docs at /api/docs/
  • Multi-format Ingestion — Ingest PDFs, DOCX, TXT, Markdown, URLs, and Obsidian vaults
  • Auto-Enrichment — Optional LLM-powered tagging, entity extraction, and memory decay
  • React Dashboard — Browse, search, and visualize your memory graph
  • Privacy-First — Runs 100% locally with Ollama; no data leaves your machine
  • Pluggable Embeddings — Ollama (default, free), OpenRouter, or bring your own provider

Architecture

┌──────────────────────────────┐
│  AI Clients                  │
│  (Claude, Cursor, Windsurf)  │
└─────────────┬────────────────┘
              │ MCP / REST
              ▼
┌──────────────────────────────────────┐
│  MCP Server (FastMCP :8080)          │
│  REST API   (Django DRF :8000)       │
│  Dashboard  (React + Vite :5173)     │
└─────────────┬────────────────────────┘
              │
   ┌──────────┴──────────┐
   │  Application Layer   │
   │  Embedder ─→ Ollama  │
   │  Auto-Tagger         │
   │  Entity Extractor    │
   │  Memory Decay        │
   └──────────┬──────────┘
              │
   ┌──────────▼──────────┐
   │  PostgreSQL 16       │
   │  + pgvector (768d)   │
   │  + Full-text search  │
   │  + HNSW index        │
   └──────────────────────┘

Quick Start

Prerequisites: Python 3.12+, PostgreSQL 16 with pgvector, Ollama (or Docker)

# Install from PyPI
pip install engram-semantic

# Or clone for development
git clone https://github.com/jblacketter/engram.git && cd engram

# 2. Start database + Ollama via Docker
docker compose up -d

# 3. Pull the embedding model
ollama pull nomic-embed-text

# 4. Install Python dependencies
pip install -e ".[dev]"

# 5. Copy environment config
cp .env.example .env

# 6. Run migrations and start the server
python manage.py migrate
python manage.py runserver

The API is now live at http://localhost:8000/api/ and docs at http://localhost:8000/api/docs/.

Start the MCP server (separate terminal):

python -m mcp_server

Start the frontend (separate terminal):

cd frontend && npm install && npm run dev

Dashboard at http://localhost:5173.

Connecting AI Clients

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "engram": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Claude Code

claude mcp add engram http://localhost:8080/mcp

Cursor / Windsurf

Add to your MCP settings:

{
  "mcpServers": {
    "engram": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

See docs/connecting-clients.md for authenticated setups and advanced config.

API Reference

REST Endpoints

Method Endpoint Description
GET /api/health/ Health check
GET /api/memories/ List memories (paginated)
POST /api/memories/ Create a memory
GET /api/memories/<id>/ Get memory by UUID
PATCH /api/memories/<id>/ Update memory
DELETE /api/memories/<id>/ Delete memory
POST /api/search/ Hybrid semantic + keyword search
GET /api/stats/ Memory statistics
GET /api/tags/ List all tags
POST /api/ingest/file/ Ingest a file (PDF, DOCX, TXT, etc.)
POST /api/ingest/url/ Scrape and ingest a URL
POST /api/ingest/batch/ Batch ingest files and URLs

Auth: Authorization: Bearer <REST_API_KEY> (disabled when env var is empty).

MCP Tools

Tool Description
store_memory Store a new memory with optional tags and importance
get_memory Retrieve a memory by UUID
update_memory Update content, tags, or importance
delete_memory Delete a memory
search_brain Hybrid search with configurable semantic/keyword weight
find_related Find semantically similar memories
list_recent_memories List recent memories, optionally filtered by source
store_from_url Fetch and ingest a URL
ingest_file Ingest a base64-encoded file
get_stats System statistics

Project Structure

engram/
├── api/                # REST API (DRF views, serializers, auth)
├── core/               # Data models, services (memory CRUD, search)
├── embeddings/         # Embedding providers (Ollama, OpenRouter)
├── intelligence/       # Auto-tagger, entity extraction, decay, reports
├── ingestion/          # File, URL, batch, and Obsidian importers
├── mcp_server/         # FastMCP server with tool definitions
├── engram/             # Django project settings and URL config
├── frontend/           # React + TypeScript + Tailwind SPA
├── docker/             # Entrypoint scripts, pgvector init SQL
├── nginx/              # Reverse proxy config (production)
├── docs/               # Extended documentation
├── tests/              # Test suite
├── Dockerfile          # Django production image
├── Dockerfile.mcp      # MCP server image
├── docker-compose.yml  # Dev: PostgreSQL + Ollama
└── pyproject.toml      # Python package config

Configuration

Key environment variables (see .env.example for the full list):

Variable Default Description
DJANGO_SECRET_KEY Django secret key
DJANGO_SETTINGS_MODULE engram.settings.development Settings module
POSTGRES_DB engram Database name
POSTGRES_HOST localhost Database host
OLLAMA_BASE_URL http://localhost:11434 Ollama API URL
OLLAMA_EMBED_MODEL nomic-embed-text Embedding model
OLLAMA_CHAT_MODEL llama3.2:3b Chat model for enrichment
OPENROUTER_API_KEY Fallback embedding provider
MCP_API_KEY MCP auth token (empty = open)
REST_API_KEY REST auth token (empty = open)
AUTO_ENRICH_ON_CREATE false Auto-tag and extract entities

Production Deployment

docker compose -f docker-compose.prod.yml up -d

This starts PostgreSQL, Ollama (with GPU support), Django (gunicorn), the MCP server, and nginx with TLS. See docs/setup-docker.md for full production setup and docs/setup-supabase.md for cloud-hosted PostgreSQL.

Tech Stack

Backend: Django 5.1 • Django REST Framework • FastMCP 2.0 • PostgreSQL 16 + pgvector • Ollama Frontend: React 18 • TypeScript • Vite • Tailwind CSS • D3 • Recharts Infra: Docker • nginx • gunicorn • uvicorn

Documentation

Guide Description
Connecting Clients Claude Desktop, Claude Code, Cursor setup
Embedding Providers Ollama, OpenRouter, OpenAI, Cohere comparison
Docker Setup Local and production Docker guide
Supabase Setup Cloud PostgreSQL with Supabase
Schema Database schema deep dive
Workflows Daily capture and search patterns
Extending Adding providers, tools, and importers
Windows LAN Deploy Deploy on a Windows server for home LAN access
Troubleshooting Common issues and fixes
Roadmap Feature roadmap

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

engram_semantic-1.0.0.tar.gz (59.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

engram_semantic-1.0.0-py3-none-any.whl (49.1 kB view details)

Uploaded Python 3

File details

Details for the file engram_semantic-1.0.0.tar.gz.

File metadata

  • Download URL: engram_semantic-1.0.0.tar.gz
  • Upload date:
  • Size: 59.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for engram_semantic-1.0.0.tar.gz
Algorithm Hash digest
SHA256 a71aa21c6e5420e0ccf8e4569d774f43ab8b3bcbdff76c73764d655611e08ff1
MD5 7532e257ec5b2f254af673269c131f65
BLAKE2b-256 195904e44e13f01926e3def8aeee8c27756539628a611dc2225675c5db120a7d

See more details on using hashes here.

Provenance

The following attestation bundles were made for engram_semantic-1.0.0.tar.gz:

Publisher: publish.yml on jblacketter/engram

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file engram_semantic-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for engram_semantic-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 add9a0635b993b6d8c2353c230c82237e67376844a536ad0658ce10f8dd8f981
MD5 f35c935c1f632d66761b10bbfd1c8fa7
BLAKE2b-256 7f4474cc1f6b56814416bec9fd327b0c1c7066b20bae9540c6534035fcd16a9a

See more details on using hashes here.

Provenance

The following attestation bundles were made for engram_semantic-1.0.0-py3-none-any.whl:

Publisher: publish.yml on jblacketter/engram

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page