Skip to main content

System overview

3ngram consists of three services sharing a single PostgreSQL database:
Frontend (Next.js 16)         Web UI for dashboard, documents, search
        │ REST API

Backend (FastAPI)             Routers > Services > Database (psycopg3 async)
        │ shared DB only
MCP Server (FastMCP)          16 tools + 3 prompts (psycopg3 sync)


PostgreSQL 16 + pgvector      documents, memories, content_chunks, clusters
The web frontend is the human interface. The MCP server is the AI interface. They share the database but never import from each other.

Tech stack

LayerTechnology
FrontendNext.js 16, React 19, TanStack Query, Tiptap/Novel editor
APIFastAPI, psycopg3 (async), Pydantic v2
MCPFastMCP, psycopg3 (sync, ConnectionPool), Streamable HTTP
DatabasePostgreSQL 16, pgvector, Alembic migrations
EmbeddingsOpenAI text-embedding-3-small (1536-dim)
AuthJWT (API), OAuth 2.0 (MCP)
CIGitHub Actions (ruff, mypy, pytest, Playwright, Bandit)

Core principles

  1. MCP-first: AI tools are the primary interface; the web app is for overview and data portability
  2. Structured memories: Commitments, decisions, blockers, and context have lifecycle semantics
  3. User isolation is mandatory: All queries filter by user_id. RLS policies enforce this at the database layer
  4. Module isolation: engram.mcp and engram.api never import each other
  5. Services own business logic: Routers handle HTTP concerns only
  6. Self-contained memories: Every memory makes sense in isolation, months later
  7. Auth can be disabled: AUTH_ENABLED=false for local single-user mode
  8. LLM consent is opt-in: Memory consolidation via external LLM defaults to off

Data model

3ngram stores three types of data:
StoreTableDescription
DocumentsdocumentsTiptap JSON. User notes edited through the web UI. Never split into chunks.
MemoriesmemoriesStructured recall. 6 types: decision, commitment, blocker, preference, pattern, context.
Content chunkscontent_chunksIndexed markdown with 1536-dim embeddings. Derived index, rebuildable.

Deployment

ServicePlatformTrigger
Backend (API + MCP)RailwayAuto-deploy on merge to main/staging
FrontendVercelAuto-deploy on merge to main/staging
DatabaseRailway (PostgreSQL)Managed
Self-hosted deployments use Docker Compose with four containers. See Self-Hosting.