Metadata-Version: 2.4
Name: contextro
Version: 0.0.1
Summary: Contextro — AI-native code intelligence MCP server: hybrid search, code graph, semantic memory, commit history, progressive disclosure, AST compression
Project-URL: Homepage, https://github.com/jassskalkat/contextro
Project-URL: Repository, https://github.com/jassskalkat/contextro
Project-URL: Documentation, https://github.com/jassskalkat/contextro/blob/main/docs/USAGE_GUIDE.md
Project-URL: Issues, https://github.com/jassskalkat/contextro/issues
Project-URL: Changelog, https://github.com/jassskalkat/contextro/releases
Author: Jass Kalkat
License-Expression: MIT
License-File: LICENSE
Keywords: ai-coding,bm25,code-analysis,code-graph,code-intelligence,code-search,commit-history,contextro,cross-repo,hybrid-search,lancedb,local-first,mcp,mcp-server,model-context-protocol,semantic-search,tree-sitter,vector-search
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: <3.14,>=3.10
Requires-Dist: ast-grep-py>=0.28.0
Requires-Dist: fastmcp>=2.0.0
Requires-Dist: lancedb>=0.4.0
Requires-Dist: onnxruntime>=1.17.0
Requires-Dist: optimum>=1.19.0
Requires-Dist: pathspec>=0.11.0
Requires-Dist: pyarrow>=14.0.0
Requires-Dist: rustworkx>=0.15.0
Requires-Dist: sentence-transformers>=3.0.0
Requires-Dist: tree-sitter-languages>=1.10.0
Requires-Dist: tree-sitter==0.21.3
Requires-Dist: watchdog>=3.0.0
Provides-Extra: dev
Requires-Dist: hypothesis>=6.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Provides-Extra: gpu
Requires-Dist: optimum[onnxruntime-gpu]>=1.19.0; extra == 'gpu'
Requires-Dist: sentence-transformers[onnx-gpu]>=3.0.0; extra == 'gpu'
Provides-Extra: model2vec
Requires-Dist: model2vec>=0.3.0; extra == 'model2vec'
Provides-Extra: reranker
Requires-Dist: flashrank>=0.2.0; extra == 'reranker'
Description-Content-Type: text/markdown

# Contextro

**Give your AI coding agent a brain.**

Contextro is a local MCP server that connects your AI agent (Claude, Cursor, Windsurf, etc.) to your codebase. Instead of reading files and guessing, your agent can search by meaning, trace call graphs, check what breaks before a refactor, search git history, and remember context across sessions — all running locally on your machine.

No cloud. No API keys. No data leaves your machine.

---

## Why Contextro?

Without Contextro, your agent reads 5–10 full files to find one function. With Contextro, it finds the exact chunk in one search call.

```
Without:  grep "auth" → read auth.py → read middleware.py → read utils.py → ...
With:     search("authentication flow") → exact result in <2ms
```

| Task | Without Contextro | With Contextro | Savings |
|---|---|---|---|
| Find a function | Read 5 files (~5000 tokens) | `search()` (~265 tokens) | **19x** |
| Trace callers | grep + read 3 files (~3000 tokens) | `find_callers()` (~16 tokens) | **187x** |
| Understand a class | Read file + grep (~2000 tokens) | `explain()` (~230 tokens) | **9x** |
| Check what breaks | Manual audit (~8000 tokens) | `impact()` (~300 tokens) | **27x** |

---

## Install

```bash
pip install contextro
```

**Requirements:** Python 3.10–3.12

Optional extras for better performance:
```bash
pip install contextro[reranker]   # Better search quality (FlashRank reranking)
pip install contextro[model2vec]  # Fast embeddings (55k/sec vs 22/sec default)
```

---

## Connect to Your Agent

### Claude Code
```bash
claude mcp add contextro -- contextro
```

### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
  "mcpServers": {
    "contextro": {
      "command": "contextro"
    }
  }
}
```

### Cursor / Windsurf / Any MCP Client
Add to your MCP configuration:
```json
{
  "contextro": {
    "command": "contextro",
    "transport": "stdio"
  }
}
```

---

## Getting Started

```
1. Tell your agent: "Index this project at /path/to/your/project"
2. Wait a few seconds (agent will poll status automatically)
3. Ask anything about your code
```

That's it. The index persists on disk — you only need to do this once per project.

---

## What You Can Do

### Search your codebase by meaning

```
search("how does authentication work")
search("database connection pool", language="python")
search("TokenBudget", mode="bm25")   ← exact keyword match
```

Contextro runs semantic search, keyword search, and graph search in parallel, then fuses the results. You get the code snippet, file path, line number, confidence level, and match type.

If results are large, you'll get a compact preview plus a `sandbox_ref` — call `retrieve(sandbox_ref)` to get the full set.

---

### Find any symbol

```
find_symbol("IndexingPipeline")           ← exact match
find_symbol("auth", exact=False)          ← fuzzy search
```

Returns the definition location, caller count, and top callers.

---

### Trace the call graph

```
find_callers("authenticate")    ← who calls this function?
find_callees("authenticate")    ← what does this function call?
```

Returns compact `name (file:line)` entries — fast and token-efficient.

---

### Understand a symbol fully

```
explain("ReciprocalRankFusion")
explain("IndexingPipeline", verbosity="summary")
```

Returns the definition, callers, callees, and related code — all in one call. Much cheaper than reading the file.

---

### Check what breaks before you change something

```
impact("TokenBudget")
impact("BaseEmbeddingService", max_depth=5)
```

Runs a transitive caller analysis. Shows every function that would be affected if you change this symbol. Always do this before renaming, deleting, or changing a function signature.

---

### AST-based code operations

The `code` tool gives you structural code intelligence:

```python
# List all symbols in a file
code(operation="get_document_symbols", file_path="src/server.py")

# Fuzzy symbol search across the codebase
code(operation="search_symbols", symbol_name="auth")

# Batch lookup with source code (one call instead of multiple find_symbol calls)
code(operation="lookup_symbols", symbols="AuthService,verify_token", include_source=True)

# Find code by structure (ast-grep patterns)
code(operation="pattern_search", pattern="def $F(self, $$$):", language="python")

# Rewrite code structurally — always preview first
code(operation="pattern_rewrite",
     pattern="logger.info($MSG)",
     replacement="logger.debug($MSG)",
     language="python",
     file_path="src/server.py",
     dry_run=True)    ← set dry_run=False to apply

# Explore a directory's structure
code(operation="search_codebase_map", path="src/auth")
```

---

### Understand project structure

```
overview()        ← file count, languages, top directories, symbol counts
architecture()    ← layers, entry points, hub symbols (most-connected classes)
analyze()         ← code smells, complexity, quality score
analyze(path="src/auth")   ← scoped to a directory
```

---

### Search git history

```
commit_search("when was the payment flow refactored")
commit_search("auth changes", author="alice")
commit_history(limit=10)
commit_history(since="2 weeks ago")
```

Finds commits by meaning, not just keywords.

---

### Remember things across sessions

```
remember("We use JWT with 24h expiry, refresh tokens in Redis")
remember("Decision: use potion-code-16m for all embeddings", memory_type="decision")
recall("JWT token expiry")
forget(tags="outdated")
```

Memories persist across sessions with optional TTL (`day`, `week`, `month`, `permanent`).

---

### Index your own docs and notes

```
knowledge(command="add", name="API docs", value="/path/to/docs/")
knowledge(command="search", query="rate limiting headers")
knowledge(command="show")     ← list all indexed knowledge bases
knowledge(command="remove", name="API docs")
```

Index any text, markdown, or code files and search them semantically.

---

### Archive and recover session context

```
compact(content)                          ← archive session content before compaction
recall(query, memory_type="archive")      ← search archived sessions later
session_snapshot()                        ← recover state after context compaction
```

When your agent's context window fills up, `compact` archives key findings and decisions. After compaction, `session_snapshot()` restores awareness of what was done, and `recall(query, memory_type="archive")` searches the archived content.

---

### Work across multiple repos

```
repo_add("/path/to/other-repo")
repo_status()
repo_remove(path="/path/to/other-repo")
```

Search across all registered repos at once.

---

### Retrieve large outputs on demand

```
retrieve("sx_abc12345")
retrieve("sx_abc12345", query="authentication")
```

Tool responses >1200 tokens are automatically sandboxed and return a compact preview with `sandbox_ref`. Use `retrieve` to fetch the full result on demand. This saves ~44% tokens on large responses while keeping your agent unblocked.

---

### Server status and health

```
status()    ← indexed?, chunks, symbols, branch, commits, cache hit rate, memory
health()    ← readiness check (use in automated pipelines)
```

---

### Look up Contextro's own docs

```
introspect(query="what tools are available")
introspect(query="how do I use pattern_search")
```

---

## All 26 Tools at a Glance

| Tool | What it does |
|---|---|
| `index` | Index a codebase (runs in background, auto-indexes git history) |
| `search` | Semantic + keyword + graph hybrid search |
| `code` | AST operations: symbol search, pattern search/rewrite, document symbols |
| `find_symbol` | Find a symbol's definition |
| `find_callers` | Who calls this function? |
| `find_callees` | What does this function call? |
| `explain` | Full symbol explanation: definition + callers + callees + related code |
| `impact` | What breaks if I change this? (transitive caller analysis) |
| `analyze` | Code smells, complexity, quality score |
| `overview` | Project structure: languages, files, directories, symbols |
| `architecture` | Layers, entry points, hub symbols |
| `commit_search` | Semantic search over git commit history |
| `commit_history` | Browse recent commits |
| `repo_add` | Register another repo for unified search |
| `repo_remove` | Unregister a repo |
| `repo_status` | View all repos and watcher status |
| `remember` | Store a note or decision with tags and TTL |
| `recall` | Search memories (and compaction archive) by meaning |
| `forget` | Delete memories |
| `knowledge` | Index and search your own docs/notes/files |
| `compact` | Archive session content before compaction |
| `session_snapshot` | Compressed session state for context recovery |
| `introspect` | Look up Contextro's own tool docs and settings |
| `retrieve` | Fetch sandboxed large output by reference ID |
| `status` | Server status, index stats, cache hit rate |
| `health` | Readiness check |

---

## How Search Works

When you call `search("how does auth work")`, Contextro:

1. Checks the query cache for a semantic or exact hit
2. Runs vector search (semantic), BM25 (keyword), and graph search (connectivity) in parallel
3. Fuses results with Reciprocal Rank Fusion
4. Optionally reranks with FlashRank
5. Filters low-relevance results (threshold: 40% of top score)
6. Applies diversity penalty (no 5 results from the same file)
7. Compresses code snippets with AST-aware compression
8. Returns confidence level (`high`/`medium`/`low`), token count, and `sandbox_ref` if needed

Every step is designed to balance relevance, speed, and token efficiency.

---

## Configuration

All settings are environment variables with the `CTX_` prefix. Most users don't need to change anything — the defaults are optimized for the best balance of speed and quality.

### Common settings

| Variable | Default | What it does |
|---|---|---|
| `CTX_STORAGE_DIR` | `~/.contextro` | Where the index is stored |
| `CTX_EMBEDDING_MODEL` | `potion-code-16m` | Embedding model (see below) |
| `CTX_AUTO_WARM_START` | `false` | Restore index on restart without re-indexing |
| `CTX_RELEVANCE_THRESHOLD` | `0.40` | How strict search filtering is (0–1) |
| `CTX_SEARCH_MODE` | `hybrid` | `hybrid`, `vector`, or `bm25` |
| `CTX_MAX_MEMORY_MB` | `350` | RAM budget |
| `CTX_COMMIT_HISTORY_ENABLED` | `true` | Index git commits for `commit_search` |
| `CTX_LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
| `CTX_TRANSPORT` | `stdio` | `stdio` (local) or `http` (Docker/remote) |

### Search tuning

| Variable | Default | What it does |
|---|---|---|
| `CTX_SEARCH_CACHE_MAX_SIZE` | `128` | Max cached search responses |
| `CTX_SEARCH_CACHE_TTL_SECONDS` | `300` | Cache expiry (seconds) |
| `CTX_SEARCH_SANDBOX_THRESHOLD_TOKENS` | `1200` | Sandbox responses above this size |
| `CTX_SEARCH_SANDBOX_TTL_SECONDS` | `600` | Sandbox expiry (seconds) |
| `CTX_SEARCH_PREVIEW_RESULTS` | `4` | Preview results when sandboxing |
| `CTX_SEARCH_PREVIEW_CODE_CHARS` | `220` | Code preview length |

### Indexing tuning

| Variable | Default | What it does |
|---|---|---|
| `CTX_CHUNK_CONTEXT_MODE` | `rich` | Chunk header style: `minimal` or `rich` |
| `CTX_SMART_CHUNK_RELATIONSHIPS_ENABLED` | `true` | Index caller→callee relationship chunks |
| `CTX_SMART_CHUNK_FILE_CONTEXT_ENABLED` | `true` | Index file-overview chunks |
| `CTX_COMMIT_HISTORY_LIMIT` | `500` | Max commits to index |
| `CTX_REALTIME_INDEXING_ENABLED` | `true` | Auto-reindex on branch switch |

### Embedding models

| Model | Speed | Quality | Best for |
|---|---|---|---|
| `potion-code-16m` ⭐ | 55k/sec | 99% of SOTA | Daily coding — best balance |
| `potion-8m` | 80k/sec | Good | Maximum speed |
| `jina-code` | 15/sec | Best | Small projects, max precision |
| `nomic-embed` | 15/sec | Good | Docs and markdown |
| `bge-small-en` | 22/sec | OK | Legacy use |

The default (`potion-code-16m`) is trained specifically on code and runs at 55,000 embeddings/sec — fast enough to reindex on every branch switch.

---

## Docker (Team / Server Use)

If you want to run Contextro on a server and share it across a team:

```yaml
# docker-compose.yml
services:
  contextro:
    container_name: contextro-mcp
    image: ghcr.io/jassskalkat/contextro-mcp:latest
    ports:
      - "8000:8000"
    volumes:
      - contextro-data:/data
      - ${CTX_CODEBASE_HOST_PATH}:/repos/platform:ro
    environment:
      CTX_STORAGE_DIR: /data/.contextro
      CTX_CODEBASE_HOST_PATH: ${CTX_CODEBASE_HOST_PATH}
      CTX_CODEBASE_MOUNT_PATH: /repos/platform
      CTX_TRANSPORT: http
      CTX_HTTP_HOST: 0.0.0.0
      CTX_HTTP_PORT: "8000"
      CTX_AUTO_WARM_START: "true"

volumes:
  contextro-data:
```

```bash
export CTX_CODEBASE_HOST_PATH=/path/to/your/project
docker compose up -d
```

The image auto-remaps your host path inside the container. Pull it directly:

```bash
docker pull ghcr.io/jassskalkat/contextro-mcp:latest
```

---

## Performance

| Metric | Value |
|---|---|
| Indexing speed | 3,349 files in 8.1s |
| Incremental reindex | 22ms (no changes) |
| Search latency | <2ms (warm index) |
| File discovery | 15ms for 3,349 files |
| Token reduction | 65–90% vs raw file reading |
| Memory usage | <350MB |
| Progressive disclosure savings | ~44% on large responses |
| AST snippet compression | ~73% on code previews |

---

## License

MIT — see [LICENSE](LICENSE) for details.
