RAG & Memory as a Service

Oreag turns your own documents into a dedicated, queryable RAG API — and a persistent memory layer for coding agents. Upload files, tune chunking and embeddings, and get a private endpoint and API key your apps can call. Bring your own provider keys; a memory graph and an MCP server expose the same knowledge to Claude Code, Codex and Claude.

RAG Agentic RAG Agent Memory MCP Next.js 16 FastAPI pgvector Supabase BYOK Multi-LLM Docs → API

Oreag

A case study by Haroon K M Scroll to read ↓
Built with
Next.js 16 React 19 TypeScript Tailwind v4 Radix UI SWR FastAPI SQLAlchemy 2 Pydantic Supabase Postgres + pgvector Redis three.js PyMuPDF MarkItDown LangChain Fernet FastMCP Docker
The thesis

Most teams want answers from their own documents — and a place for their agents to remember — not another vector database to operate. Oreag turns a folder of files into a production retrieval API and a memory layer: conversion, chunking, embeddings, retrieval and grounded generation are handled, so any app gets cited answers from a single call — and any coding agent can save, recall and search the same knowledge over MCP.

See it live

From documents to a queryable API — and agent memory

Spin up a project from the dashboard, upload documents, and Oreag indexes them in the background. Query the endpoint for answers grounded in your sources — filename, page and similarity for every citation — or connect an agent over MCP to save and recall what it learns.

Open live demo →
01
The pipeline

How it works

From an uploaded document to a grounded, cited answer — the stages that turn raw files into a retrieval API.

01

Upload

Drop files into a project — 29 formats, from PDF, DOCX and PPTX to spreadsheets, images and audio. Each file is stored in a private Supabase bucket, written as a pending row, and queued as a background task.

02

Convert

MarkItDown turns every file into clean Markdown — PyMuPDF counts the pages — preserving headings and structure so retrieval and the memory graph stay context-aware.

03

Chunk

A recursive splitter breaks the Markdown into overlapping chunks — 1000 characters with 200 overlap by default, tunable per project or overridden per file.

04

Embed

Each chunk is vectorised through your chosen provider — from OpenAI, Gemini and Azure to local Ollama and sentence-transformers — in provider-tuned batches. Matryoshka-capable models expose several vector sizes: shrinking to a smaller one truncates the stored vectors in place, instantly, with no re-embedding. Re-runs are idempotent: prior vectors are deleted first, so re-indexing never duplicates.

05

Index

Vectors land in Postgres via pgvector; each file flips to indexed and the project status recomputes — empty → indexing → ready, or error if a file fails.

06

Retrieve

On a cache miss, retrieval runs hybrid: a semantic pgvector search — ORDER BY embedding <=> qvec — for meaning, and a Postgres full-text search for exact terms like error codes, names and IDs, fused by Reciprocal Rank Fusion. The top-k results (capped at 20) each carry filename, page and similarity. Broad questions trigger an agentic loop — focused sub-queries, a second pass when the first is thin — and any saved agent memories that clear a similarity bar are blended in as extra sources.

07

Generate

An LLM composes an answer strictly from that context, cited [1] [2] back to filename and page — and every query is logged with its latency. A two-layer cache sits in front: an exact-match layer (L1, Redis) serves identical repeats instantly, and a semantic layer (L2, pgvector) serves questions that merely mean the same — a cosine match above 0.75 — so a rephrase never pays the model twice. One call in, a grounded answer out.

02
Capabilities

What it does

Everything between a pile of documents and a production answer endpoint — self-serve, from a web dashboard.

Documents → query API

Upload 29 file types and get a dedicated REST endpoint plus an oreag_sk_ API key to query them from any app or agent.

BYOK, multi-provider

Thirteen bring-your-own-key cloud providers — OpenAI, Gemini, Azure, Anthropic, Mistral, Cohere, Groq, xAI and more — plus three keyless local ones: Ollama, LM Studio and sentence-transformers. Keys are Fernet-encrypted at rest, per-account or per-project.

Cited, grounded answers

Every response returns the answer plus its source chunks — filename, page and similarity — the model used, and the query latency.

Agent memory graph

A /memory-graph endpoint returns the project as project → file → section → chunk and memory nodes, joined by auto-detected cross-document related links to traverse.

Tunable retrieval

Pick the embedding provider, model and LLM; set chunk size, overlap and top-k globally or per file — with one-click re-index.

Self-serve dashboard

Files, Memory, Playground, API, Visualize and Settings tabs — upload documents, test queries live, copy code snippets, explore the knowledge graph and manage keys.

Agentic retrieval

Broad questions are decomposed into several targeted sub-queries, retrieved over a couple of rounds, and answered with the right depth — or returned with clarifying questions when the evidence is too thin.

Conversation memory

Pass a conversation_id and follow-ups like “summarise that” are rewritten into standalone questions against the running thread — multi-turn dialogue, server-side, with an optional Redis store.

3D knowledge graph

The Visualize tab renders the whole project — files, chunks and memories as nodes joined by similarity edges — as an interactive WebGL graph. Rotate, zoom, hover for a tooltip, click a node to read its text and jump straight to the source file.

Two-layer answer cache

Repeats never re-run the model: an exact-match layer in Redis (L1) and a semantic layer in pgvector (L2) serve identical and reworded questions from cache — the serving layer and its similarity are surfaced right in the playground.

03
Agent memory · MCP

Memory for agents

Connect Claude Code, Codex or Claude to one project with its API key. The Oreag MCP server (FastMCP) gives an agent persistent memory and document recall across sessions — running locally over stdio, or as a remote multi-tenant connector at /projects/<id>/mcp. These six are the documented core; three more — add_document, get_memory_graph and explore_brain — complete a set of nine.

list_recent_memory

Pull recent and pinned memories at the start of a session to orient the agent — pinned entries always surface first.

save_memory

Persist a decision, fact or note — with tags and an optional pin — embedded on save so it can be recalled later.

search_memory

Recall the most relevant saved memories for the current task by cosine similarity over the project's memory store.

search_docs

Search the project's uploaded documents for relevant passages — retrieval only, no LLM call.

ask_docs

Ask a question and get a grounded, cited answer straight from the project's documents — the same pipeline as the public API.

delete_memory

Remove a memory entry by id when it's stale or wrong, keeping the agent's recall clean over time.

04
Under the hood

How it's built

A multi-tenant, bring-your-own-key platform across five tiers — and the engineering decisions behind a retrieval API you don't have to babysit.

16
AI providers — BYOK or local
29
Supported file types
≤20
Sources per grounded answer
  • Multi-tenant and bring-your-own-key: every user's data is isolated by Postgres Row-Level Security, provider keys are Fernet-encrypted, and API keys are stored only as SHA-256 hashes behind Supabase Auth (JWT / JWKS).
  • Documents become structured Markdown before chunking, so headings and tables survive into both retrieval and the memory graph.
  • Broad questions run an agentic loop that plans up to five sub-queries across as many as two retrieval rounds before composing a single grounded answer.
  • A two-layer answer cache fronts every query surface — the playground, the public API and MCP alike: an exact-match layer (Redis, L1) serves identical repeats and collapses simultaneous asks into one model call, while a semantic layer (pgvector, L2) serves reworded questions whose cosine similarity clears 0.75 — a rephrase costs one embedding, not a full retrieval and generation.
  • Retrieval is hybrid, and only runs on a cache miss: a semantic vector search and a Postgres full-text search run together and are fused by Reciprocal Rank Fusion, so exact tokens — error codes, part numbers, names — surface alongside meaning matches.
  • Matryoshka-aware embeddings let a project shrink its vector dimensions on the same model with no re-embedding: stored chunk and memory vectors are truncated in place and re-normalised in a single pass, while a model switch re-embeds documents and memories together.
  • The knowledge space is explorable in 3D — a WebGL force graph of files, chunks and memories with similarity edges — so a user can see how their documents cluster and relate at a glance, and jump from any node to its source.
  • Re-indexing is idempotent — a re-run deletes prior vectors first, so “update memory” never duplicates content.
  • The memory graph auto-links the nearest chunks across different files when cosine similarity ≥ 0.6, and a separate /explore walks those related edges outward from the best matches — a guided traversal rather than a flat top-k.
  • Ingestion runs as background tasks that never block the dashboard, and any job left mid-flight by a restart is caught on startup and marked failed — never left hanging — so a one-click retry re-runs it.
  • The same vector machinery powers documents and agent memory: memories are embedded on save and recalled by cosine similarity, with the recent-memory view surfacing pinned entries first.
  • Every query is logged with its latency, and answers ship with per-source similarity for traceability.
By the numbers
1
API call from question to answer
100%
Bring-your-own keys & data
0
Infrastructure you manage