engram
Supports ingesting notes and content from Obsidian vaults into the semantic memory store.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@engramremember that my dog's name is Max"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 runserverThe 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_serverStart the frontend (separate terminal):
cd frontend && npm install && npm run devDashboard 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/mcpCursor / 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 |
|
| Health check |
|
| List memories (paginated) |
|
| Create a memory |
|
| Get memory by UUID |
|
| Update memory |
|
| Delete memory |
|
| Hybrid semantic + keyword search |
|
| Memory statistics |
|
| List all tags |
|
| Ingest a file (PDF, DOCX, TXT, etc.) |
|
| Scrape and ingest a URL |
|
| Batch ingest files and URLs |
Auth: Authorization: Bearer <REST_API_KEY> (disabled when env var is empty).
MCP Tools
Tool | Description |
| Store a new memory with optional tags and importance |
| Retrieve a memory by UUID |
| Update content, tags, or importance |
| Delete a memory |
| Hybrid search with configurable semantic/keyword weight, filterable by |
| Find semantically similar memories, filterable by |
| List recent memories, optionally filtered by |
| Fetch and ingest a URL |
| Ingest a base64-encoded file |
| 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:
A scoping tag in the
tagsfield —domain:<name>, optionally refined withproject:<slug>. Examples:tags=["domain:qa", "project:my-app"]tags=["domain:personal"]
The
sourcefield — already part of the schema — to identify the writer (e.g."aegis","qaagent","mcp","manual").sourceis 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 |
|
|
MCP | yes | yes |
MCP | yes | yes |
MCP | yes | yes |
REST | 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/tenantfield exists. If you later need hard isolation, options are: run two Engram instances on separate databases, or add aworkspaceschema 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 configConfiguration
Key environment variables (see .env.example for the full list):
Variable | Default | Description |
| — | Django secret key |
|
| Settings module |
|
| Database name |
|
| Database host |
|
| Ollama API URL |
|
| Embedding model |
|
| Chat model for enrichment |
| — | Fallback embedding provider |
| — | MCP auth token (empty = open) |
| — | REST auth token (empty = open) |
|
| Auto-tag and extract entities |
Production Deployment
docker compose -f docker-compose.prod.yml up -dThis 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 |
Claude Desktop, Claude Code, Cursor setup | |
Ollama, OpenRouter, OpenAI, Cohere comparison | |
Local and production Docker guide | |
Cloud PostgreSQL with Supabase | |
Database schema deep dive | |
Daily capture and search patterns | |
Adding providers, tools, and importers | |
Deploy on a Windows server for home LAN access | |
Common issues and fixes | |
Feature roadmap |
License
MIT
This server cannot be installed
Maintenance
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
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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