← All work

CASE STUDY · 2026

GraphRAG in TypeScript

A reference implementation that keeps the graph, the embeddings and the citations in one PostgreSQL database, and reruns only what changed.

SCOPE
Engine, Docker stack, MCP server
STACK
TypeScript · Bun · PostgreSQL + pgvector · MCP
STATUS
Open source, active

01 PROBLEM

The reference GraphRAG implementations assume Python. A TypeScript service that wants graph-shaped retrieval has two options: bolt on a Python sidecar, or give up and use plain vector search. The sidecar doubles the deployment surface; plain vector search loses the relationships that make the corpus worth graphing in the first place.

02 DECISIONS

  1. One database for graph and vectors

    PostgreSQL with pgvector stores entities, relationships and embeddings side by side. One backup, one migration path, one connection string instead of two stores kept in sync.

  2. Leiden, not Louvain

    Community detection runs through Leiden with deterministic post-processing. The hierarchy is what makes an incremental run comparable with the previous one; Louvain's ordering noise shows up as communities that move for no reason.

  3. Reciprocal rank fusion across channels

    Vector, keyword and graph neighbours are combined with RRF instead of a single tuned weight. Each channel keeps its own score scale, and a channel that is having a bad day does not drag the others down.

  4. Reuse the expensive step

    Community summaries are the costly LLM call. An incremental build diffs the corpus, re-summarises only communities whose membership changed, and leaves the rest untouched.

  5. MCP as the interface

    The engine ships an MCP server with isolated workspaces, so an editor or an agent can query it without an SDK, and a second corpus does not leak into the first.

03 RESULT

Strict hits, 12 queries10 / 12 (83.3%)
Average entity and phrase recall95.8%
Indexing time / average query12m 19s / 22.5s
Incremental build after one document changed5m 11s, recall 50% → 100%

CAVEATSThese numbers come from a self-run benchmark: 12 queries over 5 chapters of public-domain text, scored by lexical entity and phrase matching rather than human grading, on a local Docker stack with a hosted chat model. They are a sanity check, not a leaderboard position.

Hire this: retrieval engineering ↗