Skip to main content
Glama

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.

Related MCP server: mcp-recall

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, filterable by tags and source

find_related

Find semantically similar memories, filterable by tags and source

list_recent_memories

List recent memories, optionally filtered by source and/or tags

store_from_url

Fetch and ingest a URL

ingest_file

Ingest a base64-encoded file

get_stats

System statistics

Scoping memories across domains

A single Engram instance can host memories from multiple domains (e.g. QA-tool output and personal notes) without cross-contamination, using tag-based soft scoping. The convention is documented here so any client can follow it.

The convention

Every write should set two things:

  1. A scoping tag in the tags field — domain:<name>, optionally refined with project:<slug>. Examples:

    • tags=["domain:qa", "project:my-app"]

    • tags=["domain:personal"]

  2. The source field — already part of the schema — to identify the writer (e.g. "aegis", "qaagent", "mcp", "manual"). source is a distinct top-level field, not a tag; the two are complementary.

Reading with scope

The MCP tools and REST search honor these on read. Examples:

# MCP
await search_brain("flaky test", tags=["domain:qa"])
await find_related(memory_id, tags=["domain:qa"])
await list_recent_memories(tags=["domain:qa"])

# REST
POST /api/search/  {"query": "flaky test", "tags": ["domain:qa"]}

Scoped read surfaces (filterable)

The following read surfaces accept tags and/or source filters, so callers that pass them can stay inside one domain:

Surface

tags

source

MCP search_brain

yes

yes

MCP find_related

yes

yes

MCP list_recent_memories

yes

yes

REST POST /api/search/

yes

yes

Residual surfaces (intentionally unscoped)

These surfaces return data across all domains regardless of caller. They are acceptable for a single-user instance; if you ever expose Engram beyond a trusted boundary, treat them as gaps to close:

  • REST GET /api/memories/ — paginated memory list, no filter args.

  • REST GET /api/memories/<id>/ — direct fetch by UUID; no tag check.

  • REST GET /api/stats/ — counts and date range across all memories.

  • REST GET /api/tags/ — full tag enumeration across all domains.

  • MCP get_stats — same as the REST stats endpoint.

  • MCP get_memory — direct UUID fetch; no tag check.

  • React dashboard — single-user view that displays all memories, recent-feed, and analytics across all domains.

Limits of soft scoping

  • Discipline-based. Engram does not enforce that writes carry a domain tag. Clients that omit it produce un-scopable memories.

  • No per-user auth. The instance is single-user; auth is global API-key.

  • No migrations involved. No workspace/tenant field exists. If you later need hard isolation, options are: run two Engram instances on separate databases, or add a workspace schema column.

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

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jblacketter/engram'

If you have feedback or need assistance with the MCP directory API, please join our Discord server