Skip to main content
Glama

Smriti

A local, CPU-only memory and context engine for coding agents: it finds the code a task needs, packs it into a token budget, and remembers facts that go stale when the code they describe changes.

CI Python Rust TypeScript MCP License

Coding agents forget everything between sessions, and they fill their context with whole files when only a few functions matter. Smriti indexes a repository, retrieves the relevant symbols with lexical, vector and graph signals, and packs them into a strict token budget. It also keeps a memory of facts, each anchored to the exact code it describes, so editing that code marks the fact stale instead of letting it mislead the next session.

An agent records "parse_header must keep the original casing", anchored to parse_header. A week later someone rewrites parse_header. On the next smriti index, the fact is marked stale, and recall --fresh-only stops returning it.


Contents

Section

What it does

The capability surface, by area

Architecture

How the pieces fit

How a context query runs

Retrieve, rank, pack

Quick start

From a clean checkout to an agent connection

Results

Measured, sourced, including where it loses

Design decisions

The tradeoffs, and why

Repository layout

Where things live

Documentation

Which file answers which question

Team

Who built it


Related MCP server: lens

What it does

Area

Capabilities

Indexing

Merkle-hashed incremental indexing; tree-sitter parsing of Python, TypeScript, Java, Go, C and C++; a file watcher

Resolution

A scope-aware call and import graph, with C3 method order for Python; uncertain targets become low-confidence may_call edges, never claimed calls

Retrieval

BM25F over symbol fields, a custom HNSW index over local ONNX MiniLM embeddings, reciprocal rank fusion and personalized PageRank over the graph

Packing

A multiple-choice knapsack that picks each symbol's representation (full body, signature or omit) under an exact tokenizer budget, with a greedy fallback

Memory

Facts anchored to symbol content hashes, with fresh, stale and orphaned states; bitemporal history with branches that follow Git, three-way merge, revert and cascading forget

Interfaces

An MCP server (14 tools), a CLI, a localhost web UI, a VS Code extension and a Docker image

Native

An optional Rust/PyO3 kernel for HNSW distance computation, with identical results to the Python path

Benchmarks

SWE-bench Lite and Verified retrieval, LongMemEval-S, a 200-commit CodeMem replay and an agent task-success harness, with the raw results committed


Architecture

The indexer turns a repository into symbols and a graph; the retriever ranks them for a query; the packer fits them to a budget. Memory sits beside the index and checks every anchored fact against the latest symbol hashes.

graph TB
    subgraph repo["Repository"]
        SRC["source files"]
    end

    subgraph index["Index (incremental)"]
        MERKLE["Merkle tree<br/>changed files only"]
        PARSE["tree-sitter parser<br/>6 languages"]
        RESOLVE["resolver<br/>calls · imports · inheritance"]
        SNAP["snapshot<br/>symbols + edges"]
    end

    subgraph retrieve["Retrieval"]
        BM25["BM25F"]
        HNSW["HNSW + ONNX embeddings<br/>optional Rust kernel"]
        RRF["rank fusion"]
        PPR["personalized PageRank"]
        PACK["knapsack packer<br/>token budget"]
    end

    subgraph memory["Memory"]
        FACTS["anchored facts"]
        HIST["bitemporal history<br/>branch · merge · revert · forget"]
    end

    subgraph clients["Clients"]
        MCP["MCP server"]
        CLI["CLI · web UI · VS Code"]
    end

    SRC --> MERKLE --> PARSE --> RESOLVE --> SNAP
    SNAP --> BM25
    SNAP --> HNSW
    BM25 --> RRF
    HNSW --> RRF
    RRF --> PPR --> PACK
    SNAP -.->|content hashes| FACTS
    FACTS --> HIST
    PACK --> MCP
    HIST --> MCP
    MCP --> CLI

How a context query runs

sequenceDiagram
    participant A as Agent
    participant S as Smriti
    participant I as Index
    participant R as Ranker
    participant P as Packer

    A->>S: context("fix header parsing", budget=8000)
    S->>I: bring the index up to date
    I-->>S: snapshot (changed files reparsed)
    S->>R: BM25F + vector search
    R->>R: fuse ranks, expand over the call graph
    R-->>S: ranked symbols
    S->>P: choose body / signature / omit per symbol
    P-->>S: context within budget (exact token count)
    S-->>A: packed context + fresh facts

Quick start

Requires Python 3.12 or newer.

# 1. Install
git clone https://github.com/guru-bharadwaj20/Smriti.git
cd Smriti
python -m venv .venv
.venv/bin/pip install -e ".[vectors,dev]"     # Windows: .venv/Scripts/pip
.venv/bin/pytest

# 2. Index a repository and query it
smriti index --root /path/to/repo
smriti context "fix header parsing for empty values" --budget 8000
smriti find-symbol parse_header
smriti callers parse_header

# 3. Remember a fact anchored to code, and watch it go stale
smriti remember "parse_header must keep the original casing" --anchor SYMBOL_ID=CONTENT_HASH
smriti recall "header casing" --fresh-only
smriti memory log

# 4. Connect a coding agent over MCP (stdio)
smriti serve --root /path/to/repo

find-symbol prints each symbol's id and content_hash for --anchor. Vector search needs the pinned ONNX model (python -m smriti.vector.download); it is never downloaded silently. The Rust kernel builds with maturin in native/. Client configuration is in docs/mcp-setup.md; a container build is in docs/docker.md.


Results

Every number below comes from a committed result file. Full tables, intervals and caveats are in docs/report.md and docs/results.md.

Code retrieval: SWE-bench Lite ∪ Verified

698 of 707 unique tasks were measured across 12 repositories; 9 were excluded because the issue text contains the fix. The table shows the held-out split (516 tasks with a gold function); tuning used only the validation split.

Method

Function recall@10

File recall@10

BM25

0.291

0.711

Exact embedding search

0.332

0.703

Smriti full

0.355

0.801

Smriti without vectors

0.273

0.715

Smriti without graph

0.385

0.784

  • Smriti beats BM25: +0.063 function recall@10, paired 95% interval [+0.030, +0.097].

  • It does not beat plain embedding search: +0.023, interval [−0.011, +0.057].

  • The graph term hurts ranking: removing it adds +0.031 [+0.009, +0.056] and makes ranking about 70× faster. Per-repository results and misses are in docs/swebench-failures.md.

Memory and other benchmarks

Benchmark

Result

CodeMem: 200 real psf/requests commits, 64 anchored facts

stale detection precision 1.0, recall 1.0 (12,736 observations)

Anchors through file moves / identifier renames

64/64 kept fresh / 64/64 flagged

Cascading forget on a derivation diamond

exact closure, 0 facts resurrected across 201 branches

LongMemEval-S (500 questions, retrieval only)

session recall@5 0.848

Memory archive compression (real replay log)

20.9% of original size, byte-identical

Rust distance kernel

HNSW build on Django 384 s → 55 s, identical graph

Agent task success

Qwen2.5-Coder-7B (CPU, temperature 0) fixed 8 injected bugs in a small fixture repository. Given Smriti's context at 1,500 tokens it solved 8/8; given only the file list it solved 0/8. Given the whole repository at the same budget it also solved 8/8, because the fixture fits in the budget, so this shows Smriti's context is sufficient, not that it beats including everything (bench/agent/README.md).


Design decisions

Local and CPU-first. Everything runs on a laptop with no service and no API key: tree-sitter, a 22 MB embedding model and pure-Python indexes, with an optional Rust kernel for the one hot loop. The cost is speed on very large repositories, which the benchmarks report rather than hide.

Freshness is structural. A fact is anchored to a symbol's content hash, so Smriti can say exactly when the code under a fact changed. It cannot say whether the fact is still true; a stale fact may still be correct. Identical-content moves keep facts fresh; renames are flagged, not guessed.

Resolution never overclaims. Static analysis misses dynamic dispatch, so uncertain targets become low-confidence may_call edges rather than confident calls.

Packing is an optimization problem. Each symbol has several representations at different token costs; a knapsack chooses among them under an exact tokenizer count instead of truncating files.

Evaluation is honest by construction. Validation and held-out splits are fixed by a hash of the instance ID; a leakage guard rejects tasks whose issue text contains the patch; failures are recorded, never scored as zero. Negative results stay in the docs, including where Smriti loses to a baseline.


Repository layout

.
├── smriti/        the engine: merkle, parse, resolve, lexical, vector, rank, pack, memory, server, ui, watch
├── native/        optional Rust/PyO3 kernel for HNSW distance computation
├── vscode/        VS Code extension (TypeScript) over the smriti CLI
├── bench/         SWE-bench, LongMemEval, CodeMem, agent and component benchmarks, with committed results
├── tests/         unit, integration and benchmark-harness tests
├── scripts/       demos, result-table generation and smoke checks
└── docs/          design, semantics, benchmarks, report, limitations

Documentation

Question

File

How is it designed, and why?

docs/architecture.md, docs/design.md

What do time, deletion and freshness mean?

docs/memory-semantics.md

How do retrieval, resolution and packing work?

docs/retrieval.md, docs/resolution.md, docs/packing.md

How do I connect an agent?

docs/mcp-setup.md

What are the results?

docs/report.md, docs/results.md

How do I reproduce them?

docs/benchmarks.md, docs/swebench-reproduction.md

What does it not do?

docs/limitations.md

How do I develop on it?

docs/development.md


Team

Member

Focus

Guru R Bharadwaj

Design, indexing and retrieval, the MCP server, the VS Code extension, benchmarks and docs


License

MIT.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides token-efficient code retrieval for coding agents by indexing repositories and enabling ranked snippet search, symbol outlines, and surgical line reads.
    4 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides AI agents with causal code memory by indexing repositories into a graph of symbols and edges, enabling context-aware retrieval of relevant code slices.
    521 PyPI
    3
    MIT