mcp-rune 0.107.0
Be star #1 Get started
SECTION IX · GUIDE 36 OF 49
Reading
7 min
Topic
retrieval · graphrag
Spec
v0.107.0
Source
09-retrieval-and-graphrag/retrieval-graphrag.md
On this page7 sections

Retrieval & GraphRAG

The architectural map for chapter IX. If you’d like to feel this working before reading the architecture, run Analysis quickstart first — it brings up pgvector and walks every summary strategy end to end against fixtures. Come back here when you want to know which piece does what.

mcp-rune doesn’t just hand an agent raw rows — it indexes a whole dataset three ways and lets the agent answer by meaning, aggregate, or stratified sample. Vectors give you semantic recall; a relationship graph and a domain registry make that recall GraphRAG-aware.

This guide frames how they fit together and which guide owns which piece.

RETRIEVAL / GRAPHRAG PIPELINE                      MiniLM-L6-v2 · 384-dim · pgvector

  ① INGEST              ② INDEX (GraphRAG)        ③ QUERY                ④ ANSWER
  ----------            ------------------        -------                --------
  your API        ┌──>  vectors                   analysis_query         findings[]
  GET /api/<m>    │     analysis_memories          · describe   ┐         stored &
  analysis_ingest │     MiniLM · 384-dim           · aggregate  │ SQL     recallable
  paginate ≤ 50   ├──>  edges                      · filter     │           │
                  │     multi-hop ingest           · sample     │           ▼
                  │     relationship graph          · path      ┘          the answer
                  ├──>  domain                      · semantic  → cosine   synthesised
                  │     DomainRegistry              9 summary strategies   0 raw rows
                  │     concepts · rules            5 field-level          in context
                  └──>  ingested_records            4 GraphRAG-aware
                        (raw JSONB · 7-day TTL)

Three indexes, one ingest

A single analysis_ingest call auto-paginates an API model into offline storage (up to 50 pages), and — depending on how it’s invoked — populates up to three indexes over the same records:

IndexWhat it storesLit up byDeep dive
Vectorsevery page summary + stored finding, embedded with all-MiniLM-L6-v2 (384-dim) in local pgvector — plus per-record embeddings on the ingested rows themselves (embed_records, default on)alwaysAnalysis Memories
Edgesrelationships between records, followed across models, persisted in ingested_edgesmulti-hop ingestAnalysis Memories
Domainconcepts + business rules that ground findings in your vocabularya DomainRegistry passed at bootDomain Knowledge

The raw rows land in an ingested_records table (JSONB rows plus optional per-record embeddings, 7-day TTL) that the SQL query modes read directly. The full dataset never crosses the context window — the agent pulls only capped, filtered/sampled slices, and otherwise works from summaries and findings.

Six query modes

analysis_query answers in six modes. Five are deterministic SQL over ingested_records and ingested_edges; one embeds the query string — and with target: "records" ranks the records themselves:

  • describe — shape of the data: counts, numeric stats, date ranges.
  • aggregateGROUP BY over fields.
  • filter — JSONB predicates (@>, range casts).
  • sample — random or stratified samples (incl. proximity buckets).
  • path — recursive-CTE typed edge chains between two records over ingested_edges: from_model/from_idto_model/to_id, with max_depth defaulting to 4 (capped at 6).
  • semantic — embeds the query string and ranks by cosine distance: stored findings and page summaries by default (target: "findings"), or the ingested records themselves (target: "records") — the record ranking composes with where for hybrid semantic + filter retrieval in one SQL statement, and with model on multi-model sessions. Pass rerank: true on target: "records" for two-stage retrieval: over-fetch by cosine, then rerank the pool with a local cross-encoder for higher precision (slower, still no API key; ADR 0018). It degrades to cosine order when the reranker model isn’t available.

On multi-model (hop-expanded) sessions, aggregate/filter/sample require the model parameter — the error names the candidate models with their record counts (see ADR 0013).

Only semantic pays for an embed (of the query, not the data). The rest are cheap, deterministic SQL.

Nine summary strategies

Every ingested page gets a page summary — the agent’s semantic “starter pack,” searchable before it has written anything. A summary strategy decides what that summary contains. The nine built-ins split by what auxiliary data they need:

  • Field-level (5) — work on records alone: distribution, coverage, anomaly, temporal, entity-extraction.
  • GraphRAG-aware (4) — need an auxiliary index:
    • relationship-coverage — requires edges
    • concept-touch — requires edges + domain
    • rule-violation — requires domain
    • semantic-cluster — requires embeddings

The dispatcher loads each strategy’s requirements lazily and silently skips any whose inputs aren’t present. See Summary Strategies.

Proximity sampling

When an investigation is anchored to a date (“show me representative records around March 15th”), sample mode takes a proximity window and date buckets so the sample spreads evenly across time instead of clustering on the densest day. See Proximity Sampling.

The six tools

The LLM drives the loop; the framework provides the seams:

ToolRole
analysis_ingestdownload once, build the indexes
analysis_queryread — describe / aggregate / filter / sample / semantic / path
analysis_storecommit a finding (embedded, recallable)
analysis_summarizere-summarize a page without re-fetching
analysis_actmutate a filtered subset server-side — IDs never return to context
analysis_cleartear down the analysis_id

Enable it

Retrieval is opt-in, and the gate has three parts: build a pgvector adapter and pass it to initVectorStorage({ adapter }), hand analysisStorageEnabled to the ToolRegistry, and spread ANALYSIS_TOOL_CLASSES into its toolClasses map — Analysis Memories → Setup shows the wiring end to end. You provide a Postgres database with the pgvector extension; embeddings run locally via MiniLM — no external vector database and no embedding API. The Analysis Quickstart brings pgvector up and walks every strategy end to end against a 5,000-record dataset.

Where to go next