Skip to main content

Stele Context

Persistent memory for AI coding agents. A zero-dependency MCP server that lets Claude Code, Claude Desktop, Cursor, and any MCP-compatible AI coding assistant remember your codebase between conversations — instead of re-reading every file from scratch.

PyPI License: MIT Python 3.10+ Zero Dependencies Tests

The Problem: AI Agents Re-Read Everything

Every new conversation with Claude Code, Cursor, or any other LLM coding tool starts from zero. The agent re-reads the same files it read yesterday, burning thousands of tokens on code that hasn't changed. On a medium-sized project that's real money and real context-window space spent re-learning what the agent already knew.

Stele Context is a local context cache that fixes this: index once, then only pay for what actually changed.

What It Does

  1. Indexes your project files once — code, docs, configs, even images and PDFs — into a local SQLite database
  2. Detects file changes with an mtime+size fast path and SHA-256 verification — unchanged files cost zero re-reads
  3. Returns a diff instead of the whole file when something did change — a 1-line edit in a 600-line file comes back as a ~60-token unified diff, not a 10,000-token re-read
  4. Searches your codebase by meaning, keyword, or exact pattern — semantic code search, BM25, and token-budgeted grep in one tool
  5. Maps how your code connects — a symbol graph for find-references, go-to-definition, and "what breaks if I change this file?" impact analysis

Everything runs 100% offline on your machine. No internet, no API keys, no cloud, no telemetry. Just Python's standard library and SQLite.

Rust 2.0 indexes images, audio, video, and PDF with the standard library alone. Python indexes imgs/* only when Pillow imports, so a zero-dependency Python run of rich 13.9.4 is 475 documents and 1097 chunks, while Rust (and Python with Pillow) is 496 documents and 1118 chunks. The 21 extra documents are the PNG and GIF files under imgs/. Rust stores header metadata for those files. Pillow stores re-encoded PNG bytes, a perceptual hash, and a histogram, so the image chunk bodies differ. Text and code stay 475 files, 1097 chunks, and 32687 symbols on both sides. Symbol edges on that tree match Python's full rebuild: 4939. impact_radius and coupling walk those edges. find_references reads the symbol table. Python 1.5.1 decodes PDFs as text and fitz.open raises FileNotFoundError; 1.5.2 reads the bytes. parity/generate_media.py rebuilds the media fixture.

Semantic search demo

Quick Start

Install

The supported package is the Rust 2.0.0 binary from the v2.0.0 GitHub Release.

curl -fsSL https://raw.githubusercontent.com/IronAdamant/stele-context/v2.0.0/scripts/install.sh | sh

Windows: scripts/install.ps1, or download stele-context-<target> from the release assets. pip install stele-context stays on 1.5.x and does not install 2.0. This 1.5.3 package prints that release URL on startup.

stele-context init .

This indexes the project (respecting .gitignore), prints a ready-to-paste MCP lite client config, and shows doctor next-steps for a cold agent. Prefer this over a bare index when wiring Stele for the first time.

Index your project

stele-context index src/ docs/ README.md

This chunks your files and stores them in a .stele-context/ folder in your project root. Indexing respects your .gitignore out of the box, so node_modules/, build output, and secrets stay out of the index.

Search your code

stele-context search "how does authentication work"
stele-context search-text "TODO" --regex
stele-context agent-grep "createApp" --group-by file

Connect it to Claude Code, Claude Desktop, or Cursor

Stele Context runs as an MCP server — the standard protocol for giving AI agents extra tools.

pip install stele-context[mcp]

Claude Code — add to ~/.claude/settings.json:

{
  "mcpServers": {
    "stele-context": {
      "command": "stele-context",
      "args": ["serve-mcp"],
      "env": { "STELE_MCP_MODE": "lite" }
    }
  }
}

Claude Desktop — add to ~/.config/Claude/claude_desktop_config.json (Linux/Mac) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "stele-context": {
      "command": "stele-context",
      "args": ["serve-mcp"],
      "env": { "STELE_MCP_MODE": "lite" }
    }
  }
}

Cursor, Windsurf, and other MCP clients — point them at the same stele-context serve-mcp command; the configuration shape is the same. (stele-context init prints a ready-to-paste snippet.)

Tip: If you installed in a virtualenv, use the full path: run which stele-context to find it.

Once connected, your agent gets the lite high-leverage tool set by default (doctor, query, agent_grep, symbols, cache, Tier-2 summaries, session provenance, plus modality utils when enabled). Set STELE_MCP_MODE=standard for the broader surface, or full for deprecated singleton tools. Exact counts come from client list_tools / tool_registry — avoid hard-coding a single integer.

doctor → query (session_id) → agent_grep / find_* as needed → get_context (trust/diff)

After edits: detect_changes. To improve hybrid search: enrichment-plan then bulk_store_summaries.

Search quality eval (CI / release gate)

python benchmarks/eval_search_quality.py --search-mode keyword --json --min-recall 0.40
python benchmarks/eval_search_quality.py --tier2-delta --min-recall 0.30

Keyword recall is gated in CI (search-regression job). The Tier-2 delta path reports hybrid recall with summaries off vs on.

Who Is This For?

  • You use Claude Code, Claude Desktop, Cursor, or another AI pair-programming tool
  • You're tired of watching your agent re-read the same files at the start of every session
  • You want to cut token costs and stop wasting context window on unchanged code
  • You want local code search that understands your project — not a cloud RAG pipeline
  • You care about supply chain security and want tooling you can audit end to end

If you've ever wished your AI coding assistant had a memory of your project, that's exactly what this is.

What Can It Do?

For everyday use

What you want How Stele helps
"Don't re-read files that haven't changed" get_context returns cached content for unchanged files — change detection via mtime+size fast path with SHA-256 verification
"Show me only what changed in a file I already read" Changed files come back with diff_since_cache — a hash-exact, token-bounded unified diff against the cached version, with a read_diff/reread_file cost recommendation
"Don't index my build output and vendored deps" Directory indexing respects .gitignore by default — anchored at your git project root, or at the indexed folder itself when there's no repo (respect_gitignore = false to opt out)
"Ask a broad question about my code" query combines semantic search, the symbol graph, and text grep into one deduplicated result list
"What files would break if I change this?" impact_radius follows the dependency chain to find affected files; significance_threshold filters noise from common symbols. Works with symbol= for dynamic/runtime hooks and direction= for outgoing or bidirectional traversal
"Which files are tightly coupled?" coupling shows shared symbols with a semantic_score that discounts generic boilerplate; mode=co_consumers catches files imported together
"Find where this function is defined and used" find_references / find_definition walk the symbol graph with a clear verdict: referenced, unreferenced, external, or not found
"Find every line matching a pattern" agent_grep does text/regex search with scope annotation, classification, and a token budget
"Run several operations in one round-trip" batch runs sequential engine methods (each manages its own locking; use engine names like index_documents)

For power users

  • Multi-agent safe — multiple AI agents share one index without stepping on each other (document locking, optimistic versioning, conflict detection)
  • Git worktree aware — each worktree gets its own index, with shared coordination across all of them
  • Session management — save and restore agent state between conversations (rollback, pruning, read-history)
  • Self-maintaining — change history and telemetry auto-prune to configurable bounds; doctor reports index health and database growth
  • Many file types — code (12 languages built in), text, Markdown, images, PDFs, audio, video (media types need optional packages)

How Many Tokens Does It Save?

What changed Tokens without Stele Tokens with Stele Savings
Nothing (same code) 10,000 0 100%
A typo fix 10,000 ~60 (the diff) 99%
Edited a few functions 10,000 ~1,000 (the diff) 90%
Rewrote the whole file 10,000 10,000 0%

The diff numbers aren't aspirational: diff_since_cache reconstructs the cached version from stored chunks, verifies it against the file's stored hash, and returns a unified diff the agent reads instead of the file. When the diff would cost more than re-reading (tiny files, total rewrites), it says so explicitly.

Zero Dependencies, By Design

pip install stele-context installs exactly one package: this one. The core runs on Python's standard library alone — the vector index (HNSW), BM25 ranking, Porter stemmer, TOML parser, diffing, and storage are all stdlib or hand-rolled and auditable in-repo.

This is a security posture, not a packaging quirk. Every dependency in an AI-agent toolchain is a supply chain attack surface — a tool your agent runs on every conversation should not pull in a dependency tree you can't read. There is no pickle anywhere (JSON-only serialization), no network code in the cache path, and ~17,000 lines of Python you can audit yourself.

Optional extras add capabilities only if you opt in:

pip install stele-context[tree-sitter]   # Better parsing for 10 more languages
pip install stele-context[image,pdf]     # Image and PDF support
pip install stele-context[performance]   # Faster math with numpy
pip install stele-context[all]           # Everything
Full extras list
Extra What it adds
performance Faster math for search (numpy, msgspec)
tree-sitter Better code parsing for JS/TS, Java, C/C++, Go, Rust, Ruby, PHP, Swift
image Index and search images (Pillow)
pdf Extract text from PDFs (pymupdf)
audio Index audio files (librosa)
video Index video keyframes (opencv)
mcp MCP server for Claude Desktop/Code
all All of the above

Python API

You can also use Stele Context directly as a Python library:

from stele_context import Stele

engine = Stele()

# Index your project
result = engine.index_documents(["src/", "README.md"])
print(f"Indexed {result['total_chunks']} chunks")

# Cached read: unchanged files come back from cache,
# changed files come back with a diff
ctx = engine.get_context(["src/main.py"])
for entry in ctx["changed"]:
    print(entry["diff_since_cache"]["diff"])

# Search by meaning or keywords
results = engine.search("authentication logic", top_k=5)
for r in results:
    print(f"{r['document_path']}: {r['content'][:100]}...")

# Check what changed since last time
changes = engine.detect_changes_and_update("my-session")
print(f"{len(changes['modified'])} files changed, {len(changes['new'])} new files")

# Find where a function/class is used
refs = engine.find_references("MyClassName")
print(f"Verdict: {refs['verdict']}")  # referenced, unreferenced, external, or not_found

# What breaks if I change this file?
impact = engine.impact_radius(document_path="src/main.py")
print(f"{impact['affected_files']} files could be affected")

Configuration

Create a .stele-context.toml in your project root to customize behavior. The same file is the project-root marker: Stele walks upward from the working directory and stops at the nearest .git or .stele-context.toml. An empty file is enough for a folder that is not a git repository. Without .git and without that file, the folder shares the global ~/.stele-context/ index with every other unmarked folder.

[stele-context]
chunk_size = 512                # How big each chunk is (in tokens)
skip_dirs = [".git", "node_modules", "dist", "vendor"]

All settings are optional — defaults work well for most projects.

All configuration options
[stele-context]
storage_dir = ".stele-context"   # Where to store the index
chunk_size = 256                 # Target tokens per chunk
max_chunk_size = 4096            # Maximum tokens per chunk
merge_threshold = 0.7            # When to merge similar adjacent chunks
change_threshold = 0.85          # When to consider a chunk "unchanged"
search_alpha = 0.42              # Balance between meaning-based and keyword search
skip_dirs = [".git", "node_modules", "__pycache__"]
respect_gitignore = true         # Skip .gitignore'd files when indexing directories
max_history_entries = 1000       # Auto-prune change history past this bound (0 = unlimited)

You can also set STELE_CONTEXT_STORAGE_DIR as an environment variable, or pass options directly in Python:

engine = Stele(chunk_size=512, skip_dirs=[".git", "node_modules", "dist"])

Priority: Python arguments > .stele-context.toml > environment variables > defaults.

Supported File Types

Built-in (no extra packages needed): .py, .js, .ts, .jsx, .tsx, .java, .cpp, .c, .h, .go, .rs, .rb, .php, .swift, .sh, .sql, .html, .css, .json, .yaml, .toml, .md, .txt, .rst, .csv, .log

With optional packages: Images (.png, .jpg, .gif, etc.), PDFs, audio (.mp3, .wav, etc.), video (.mp4, .avi, etc.)

Troubleshooting

ImportError: No module named 'stele_context' Make sure it's installed: pip install stele-context. If using a virtualenv, activate it first.

MCP server not connecting Use the full path to the binary. Run which stele-context and put that path in your config.

PermissionError when indexing Another agent might be holding a lock. Run the reap_expired_locks action of the document_lock tool to clean up.

diff_exact: false on files indexed by an older version Caches built before v1.4.1 reconstruct diffs on a best-effort basis. Re-index the file once (stele-context index <file>) and diffs become hash-exact from then on. No migration needed.

Tools report an old version or stale package metadata A leftover *.egg-info/ directory in your project root shadows the installed package's metadata for any Python started there. stele-context doctor flags this as a stale_egg_info environment issue — delete the directory or rebuild the package.

FAQ

How do I make Claude Code remember my project between conversations? Install Stele Context and add it as an MCP server (see Quick Start). Once connected, Claude Code can index your project and recall file contents, symbol locations, and code structure across conversations — without re-reading everything.

How does this reduce AI token costs on a large codebase? Unchanged files are served from the local cache at zero read cost, and changed files come back as a unified diff instead of full content. The agent's context window holds what's new, not what it already saw.

Does this work with Cursor, Windsurf, or other AI coding tools? Yes. Stele Context speaks MCP, the standard protocol for agent tools — any MCP-compatible client can use it. There's also an HTTP REST API and a plain Python library for direct integration.

Does it replace grep, file reads, or my editor's search? No — it complements them. Native tools stay best for one-off lookups; Stele adds the memory layer: what was already read, what changed since, and how symbols connect across files. Its agent_grep also auto-caches every file it searches, so searching and caching happen in one step.

Does it need an internet connection or API keys? No. Everything runs locally — local-first by design. No API calls, no cloud, no model downloads, no telemetry.

Is my code safe? Your code never leaves your machine. Zero third-party dependencies means no dependency tree to trust — about 17,000 lines of stdlib-only Python you can read and audit yourself, with JSON-only serialization (no pickle).

Can multiple AI agents use it at the same time? Yes. Built-in document locking, optimistic version tracking, and a conflict log let parallel agents share one index safely — including across git worktrees.

Where is the data stored? In a .stele-context/ folder in your project root. It's a SQLite database plus index files. Each git worktree gets its own, and history tables auto-prune so it doesn't grow unbounded.

The root is the nearest directory, walking up from where you launched Stele, that contains .git or a .stele-context.toml file. A directory with neither does not get its own index: storage falls back to ~/.stele-context/, and every other unmarked folder shares that one index. Add an empty .stele-context.toml at a non-git project's root to give that project its own index. A marker inside a git checkout wins over the higher .git when you launch Stele from that subtree, and a nearer .git wins over a marker higher up.

How is this different from CLAUDE.md or project memory files? CLAUDE.md gives your agent instructions. Stele Context gives it a searchable index of your entire codebase — every function, every import, every file relationship — plus change tracking, so it can answer "where is this used?" or "what changed since I last read this?" without re-reading anything.

Learn More

Benchmarks

Measured with bench/bench.py on Linux 6.12.94+ x86_64, 4 vCPU, rustc 1.99.1, release build, 5 runs, rich 13.9.4 (496 documents after image indexing). The Python column is the recorded 1.5.1 floor from an 8 vCPU host (bench/baseline/summary.json). Every Rust median is strictly below that floor.

Command Rust median Rust min–max Peak RSS Python 1.5.1 median
cli --version (startup) 1.8 ms 1.7–2.5 10.5 MB 79.4 ms
cli --help 1.7 ms 1.7–1.8 10.6 MB 75.7 ms
cli index . (cold, empty store) 8849.8 ms 8823.0–8860.3 82.8 MB 10656.1 ms
cli index . (warm, nothing changed) 72.6 ms 71.7–75.8 69.6 MB 197.8 ms
cli detect (nothing changed) 66.7 ms 66.4–66.9 69.7 MB 167.9 ms
cli stats 62.7 ms 62.7–62.8 69.6 MB 162.5 ms
cli doctor 50.6 ms 50.5–51.2 52.0 MB 189.7 ms
cli map --json 97.5 ms 97.2–97.7 69.6 MB 163.3 ms
cli project-brief --json 61.4 ms 61.2–62.2 69.7 MB 165.5 ms
cli search hybrid --json 72.2 ms 72.1–72.3 69.6 MB 169.0 ms
cli search keyword --json 71.9 ms 71.5–72.3 69.6 MB 161.2 ms
cli search-text --json 62.5 ms 62.0–62.9 69.6 MB 141.9 ms
cli agent-grep --json 63.9 ms 63.7–93.6 69.7 MB 228.3 ms
cli query --json 73.3 ms 72.9–74.0 69.7 MB 193.5 ms
cli find-definition --json 61.8 ms 61.5–62.2 69.6 MB 141.4 ms
cli find-references --json 63.7 ms 63.3–64.0 69.7 MB 166.2 ms
cli impact-radius --json 66.9 ms 66.7–67.4 69.7 MB 179.6 ms
cli coupling --json 63.4 ms 63.0–63.5 69.7 MB 185.3 ms
cli enrichment-plan --json 62.4 ms 62.0–68.9 69.7 MB 137.7 ms
cli history --json 61.7 ms 61.2–61.9 69.7 MB 135.1 ms

Development

pip install -e ".[dev]"
pytest                              # full suite (count grows; see CI / pytest collection)
pytest --cov=stele_context           # With coverage
mypy stele_context/                 # Type checking
ruff check stele_context/           # Linting

Releases

Releases are managed using the stele-context release command. See docs/release-automation.md for the release policy and Grok Build automation details.

Contributing

See CONTRIBUTING.md for guidelines.

License

MIT License — see LICENSE for details.

Metadata

Release files for stele-context 1.5.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stele-context 1.5.3
File Size Uploaded Provenance Actions
stele_context-1.5.3.tar.gz 227.6 kB With provenance Details for stele_context-1.5.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for stele-context 1.5.3
File Interpreter ABI Platform Actions
stele_context-1.5.3-py3-none-any.whl Python 3 none any Details for stele_context-1.5.3-py3-none-any.whl

Total release size: 445.1 kB

Release files / stele_context-1.5.3.tar.gz

Download URL stele_context-1.5.3.tar.gz
Size 227.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9b33cc886150f770fe87067427bcb51f217cf9881938af93d5e78a627ef0765f
BLAKE2b-256 checksum
How to use checksums
931575ee2ddbcd189a9bdd3fe8f10b4a86148db8a09d882442fd6bc35ed5e222
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Release files / stele_context-1.5.3-py3-none-any.whl

Download URL stele_context-1.5.3-py3-none-any.whl
Size 217.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2ef2b5c8aef72ab8a495c3b5151fea5c1566e012eafa22c8ab0ad5fe2ed4a62e
BLAKE2b-256 checksum
How to use checksums
c112795c5ba2b2a5573803f07e72982df4b88d5f0a8b3d30ea623c197619a90c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Security for stele-context 1.5.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for stele_context-1.5.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page