contextro 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- contextro-0.0.1.dist-info/METADATA +493 -0
- contextro-0.0.1.dist-info/RECORD +70 -0
- contextro-0.0.1.dist-info/WHEEL +4 -0
- contextro-0.0.1.dist-info/entry_points.txt +2 -0
- contextro-0.0.1.dist-info/licenses/LICENSE +21 -0
- contextro_mcp/__init__.py +3 -0
- contextro_mcp/accelerator.py +321 -0
- contextro_mcp/analysis/__init__.py +0 -0
- contextro_mcp/analysis/code_analyzer.py +237 -0
- contextro_mcp/config.py +248 -0
- contextro_mcp/core/__init__.py +0 -0
- contextro_mcp/core/exceptions.py +77 -0
- contextro_mcp/core/graph_models.py +276 -0
- contextro_mcp/core/interfaces.py +53 -0
- contextro_mcp/core/models.py +285 -0
- contextro_mcp/engines/__init__.py +0 -0
- contextro_mcp/engines/bm25_engine.py +153 -0
- contextro_mcp/engines/fusion.py +208 -0
- contextro_mcp/engines/graph_engine.py +285 -0
- contextro_mcp/engines/live_grep.py +169 -0
- contextro_mcp/engines/output_sandbox.py +140 -0
- contextro_mcp/engines/query_cache.py +163 -0
- contextro_mcp/engines/reranker.py +117 -0
- contextro_mcp/engines/vector_engine.py +209 -0
- contextro_mcp/execution/__init__.py +11 -0
- contextro_mcp/execution/ast_compression.py +187 -0
- contextro_mcp/execution/compaction.py +310 -0
- contextro_mcp/execution/interfaces.py +31 -0
- contextro_mcp/execution/response_policy.py +303 -0
- contextro_mcp/execution/runtime.py +73 -0
- contextro_mcp/execution/search.py +446 -0
- contextro_mcp/formatting/__init__.py +0 -0
- contextro_mcp/formatting/response_builder.py +121 -0
- contextro_mcp/formatting/token_budget.py +59 -0
- contextro_mcp/formatting/toon_encoder.py +81 -0
- contextro_mcp/git/__init__.py +1 -0
- contextro_mcp/git/branch_watcher.py +258 -0
- contextro_mcp/git/commit_indexer.py +564 -0
- contextro_mcp/git/cross_repo.py +210 -0
- contextro_mcp/indexing/__init__.py +14 -0
- contextro_mcp/indexing/chunk_context.py +110 -0
- contextro_mcp/indexing/chunker.py +144 -0
- contextro_mcp/indexing/embedding_service.py +429 -0
- contextro_mcp/indexing/file_discovery.py +95 -0
- contextro_mcp/indexing/parallel_indexer.py +141 -0
- contextro_mcp/indexing/pipeline.py +865 -0
- contextro_mcp/indexing/smart_chunker.py +223 -0
- contextro_mcp/memory/__init__.py +0 -0
- contextro_mcp/memory/compaction_archive.py +131 -0
- contextro_mcp/memory/memory_store.py +305 -0
- contextro_mcp/memory/session_tracker.py +146 -0
- contextro_mcp/middleware/__init__.py +1 -0
- contextro_mcp/middleware/audit.py +83 -0
- contextro_mcp/parsing/__init__.py +0 -0
- contextro_mcp/parsing/astgrep_parser.py +497 -0
- contextro_mcp/parsing/file_watcher.py +162 -0
- contextro_mcp/parsing/language_registry.py +274 -0
- contextro_mcp/parsing/treesitter_parser.py +421 -0
- contextro_mcp/persistence/__init__.py +0 -0
- contextro_mcp/persistence/store.py +196 -0
- contextro_mcp/research/__init__.py +13 -0
- contextro_mcp/research/catalog.py +256 -0
- contextro_mcp/schemas/__init__.py +59 -0
- contextro_mcp/schemas/inputs.py +218 -0
- contextro_mcp/schemas/responses.py +257 -0
- contextro_mcp/security/__init__.py +1 -0
- contextro_mcp/security/permissions.py +106 -0
- contextro_mcp/security/rate_limiter.py +87 -0
- contextro_mcp/server.py +3110 -0
- contextro_mcp/state.py +283 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: contextro
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Contextro — AI-native code intelligence MCP server: hybrid search, code graph, semantic memory, commit history, progressive disclosure, AST compression
|
|
5
|
+
Project-URL: Homepage, https://github.com/jassskalkat/contextro
|
|
6
|
+
Project-URL: Repository, https://github.com/jassskalkat/contextro
|
|
7
|
+
Project-URL: Documentation, https://github.com/jassskalkat/contextro/blob/main/docs/USAGE_GUIDE.md
|
|
8
|
+
Project-URL: Issues, https://github.com/jassskalkat/contextro/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/jassskalkat/contextro/releases
|
|
10
|
+
Author: Jass Kalkat
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
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
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Requires-Python: <3.14,>=3.10
|
|
23
|
+
Requires-Dist: ast-grep-py>=0.28.0
|
|
24
|
+
Requires-Dist: fastmcp>=2.0.0
|
|
25
|
+
Requires-Dist: lancedb>=0.4.0
|
|
26
|
+
Requires-Dist: onnxruntime>=1.17.0
|
|
27
|
+
Requires-Dist: optimum>=1.19.0
|
|
28
|
+
Requires-Dist: pathspec>=0.11.0
|
|
29
|
+
Requires-Dist: pyarrow>=14.0.0
|
|
30
|
+
Requires-Dist: rustworkx>=0.15.0
|
|
31
|
+
Requires-Dist: sentence-transformers>=3.0.0
|
|
32
|
+
Requires-Dist: tree-sitter-languages>=1.10.0
|
|
33
|
+
Requires-Dist: tree-sitter==0.21.3
|
|
34
|
+
Requires-Dist: watchdog>=3.0.0
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: hypothesis>=6.0.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
41
|
+
Provides-Extra: gpu
|
|
42
|
+
Requires-Dist: optimum[onnxruntime-gpu]>=1.19.0; extra == 'gpu'
|
|
43
|
+
Requires-Dist: sentence-transformers[onnx-gpu]>=3.0.0; extra == 'gpu'
|
|
44
|
+
Provides-Extra: model2vec
|
|
45
|
+
Requires-Dist: model2vec>=0.3.0; extra == 'model2vec'
|
|
46
|
+
Provides-Extra: reranker
|
|
47
|
+
Requires-Dist: flashrank>=0.2.0; extra == 'reranker'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# Contextro
|
|
51
|
+
|
|
52
|
+
**Give your AI coding agent a brain.**
|
|
53
|
+
|
|
54
|
+
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.
|
|
55
|
+
|
|
56
|
+
No cloud. No API keys. No data leaves your machine.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Why Contextro?
|
|
61
|
+
|
|
62
|
+
Without Contextro, your agent reads 5–10 full files to find one function. With Contextro, it finds the exact chunk in one search call.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Without: grep "auth" → read auth.py → read middleware.py → read utils.py → ...
|
|
66
|
+
With: search("authentication flow") → exact result in <2ms
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Task | Without Contextro | With Contextro | Savings |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| Find a function | Read 5 files (~5000 tokens) | `search()` (~265 tokens) | **19x** |
|
|
72
|
+
| Trace callers | grep + read 3 files (~3000 tokens) | `find_callers()` (~16 tokens) | **187x** |
|
|
73
|
+
| Understand a class | Read file + grep (~2000 tokens) | `explain()` (~230 tokens) | **9x** |
|
|
74
|
+
| Check what breaks | Manual audit (~8000 tokens) | `impact()` (~300 tokens) | **27x** |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install contextro
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Requirements:** Python 3.10–3.12
|
|
85
|
+
|
|
86
|
+
Optional extras for better performance:
|
|
87
|
+
```bash
|
|
88
|
+
pip install contextro[reranker] # Better search quality (FlashRank reranking)
|
|
89
|
+
pip install contextro[model2vec] # Fast embeddings (55k/sec vs 22/sec default)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Connect to Your Agent
|
|
95
|
+
|
|
96
|
+
### Claude Code
|
|
97
|
+
```bash
|
|
98
|
+
claude mcp add contextro -- contextro
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Claude Desktop
|
|
102
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"contextro": {
|
|
107
|
+
"command": "contextro"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Cursor / Windsurf / Any MCP Client
|
|
114
|
+
Add to your MCP configuration:
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"contextro": {
|
|
118
|
+
"command": "contextro",
|
|
119
|
+
"transport": "stdio"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Getting Started
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
1. Tell your agent: "Index this project at /path/to/your/project"
|
|
130
|
+
2. Wait a few seconds (agent will poll status automatically)
|
|
131
|
+
3. Ask anything about your code
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
That's it. The index persists on disk — you only need to do this once per project.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## What You Can Do
|
|
139
|
+
|
|
140
|
+
### Search your codebase by meaning
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
search("how does authentication work")
|
|
144
|
+
search("database connection pool", language="python")
|
|
145
|
+
search("TokenBudget", mode="bm25") ← exact keyword match
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
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.
|
|
149
|
+
|
|
150
|
+
If results are large, you'll get a compact preview plus a `sandbox_ref` — call `retrieve(sandbox_ref)` to get the full set.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### Find any symbol
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
find_symbol("IndexingPipeline") ← exact match
|
|
158
|
+
find_symbol("auth", exact=False) ← fuzzy search
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Returns the definition location, caller count, and top callers.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Trace the call graph
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
find_callers("authenticate") ← who calls this function?
|
|
169
|
+
find_callees("authenticate") ← what does this function call?
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Returns compact `name (file:line)` entries — fast and token-efficient.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Understand a symbol fully
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
explain("ReciprocalRankFusion")
|
|
180
|
+
explain("IndexingPipeline", verbosity="summary")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Returns the definition, callers, callees, and related code — all in one call. Much cheaper than reading the file.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### Check what breaks before you change something
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
impact("TokenBudget")
|
|
191
|
+
impact("BaseEmbeddingService", max_depth=5)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
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.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### AST-based code operations
|
|
199
|
+
|
|
200
|
+
The `code` tool gives you structural code intelligence:
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
# List all symbols in a file
|
|
204
|
+
code(operation="get_document_symbols", file_path="src/server.py")
|
|
205
|
+
|
|
206
|
+
# Fuzzy symbol search across the codebase
|
|
207
|
+
code(operation="search_symbols", symbol_name="auth")
|
|
208
|
+
|
|
209
|
+
# Batch lookup with source code (one call instead of multiple find_symbol calls)
|
|
210
|
+
code(operation="lookup_symbols", symbols="AuthService,verify_token", include_source=True)
|
|
211
|
+
|
|
212
|
+
# Find code by structure (ast-grep patterns)
|
|
213
|
+
code(operation="pattern_search", pattern="def $F(self, $$$):", language="python")
|
|
214
|
+
|
|
215
|
+
# Rewrite code structurally — always preview first
|
|
216
|
+
code(operation="pattern_rewrite",
|
|
217
|
+
pattern="logger.info($MSG)",
|
|
218
|
+
replacement="logger.debug($MSG)",
|
|
219
|
+
language="python",
|
|
220
|
+
file_path="src/server.py",
|
|
221
|
+
dry_run=True) ← set dry_run=False to apply
|
|
222
|
+
|
|
223
|
+
# Explore a directory's structure
|
|
224
|
+
code(operation="search_codebase_map", path="src/auth")
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### Understand project structure
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
overview() ← file count, languages, top directories, symbol counts
|
|
233
|
+
architecture() ← layers, entry points, hub symbols (most-connected classes)
|
|
234
|
+
analyze() ← code smells, complexity, quality score
|
|
235
|
+
analyze(path="src/auth") ← scoped to a directory
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### Search git history
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
commit_search("when was the payment flow refactored")
|
|
244
|
+
commit_search("auth changes", author="alice")
|
|
245
|
+
commit_history(limit=10)
|
|
246
|
+
commit_history(since="2 weeks ago")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Finds commits by meaning, not just keywords.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
### Remember things across sessions
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
remember("We use JWT with 24h expiry, refresh tokens in Redis")
|
|
257
|
+
remember("Decision: use potion-code-16m for all embeddings", memory_type="decision")
|
|
258
|
+
recall("JWT token expiry")
|
|
259
|
+
forget(tags="outdated")
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Memories persist across sessions with optional TTL (`day`, `week`, `month`, `permanent`).
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### Index your own docs and notes
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
knowledge(command="add", name="API docs", value="/path/to/docs/")
|
|
270
|
+
knowledge(command="search", query="rate limiting headers")
|
|
271
|
+
knowledge(command="show") ← list all indexed knowledge bases
|
|
272
|
+
knowledge(command="remove", name="API docs")
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Index any text, markdown, or code files and search them semantically.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### Archive and recover session context
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
compact(content) ← archive session content before compaction
|
|
283
|
+
recall(query, memory_type="archive") ← search archived sessions later
|
|
284
|
+
session_snapshot() ← recover state after context compaction
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
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.
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### Work across multiple repos
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
repo_add("/path/to/other-repo")
|
|
295
|
+
repo_status()
|
|
296
|
+
repo_remove(path="/path/to/other-repo")
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Search across all registered repos at once.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
### Retrieve large outputs on demand
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
retrieve("sx_abc12345")
|
|
307
|
+
retrieve("sx_abc12345", query="authentication")
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
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.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
### Server status and health
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
status() ← indexed?, chunks, symbols, branch, commits, cache hit rate, memory
|
|
318
|
+
health() ← readiness check (use in automated pipelines)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
### Look up Contextro's own docs
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
introspect(query="what tools are available")
|
|
327
|
+
introspect(query="how do I use pattern_search")
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## All 26 Tools at a Glance
|
|
333
|
+
|
|
334
|
+
| Tool | What it does |
|
|
335
|
+
|---|---|
|
|
336
|
+
| `index` | Index a codebase (runs in background, auto-indexes git history) |
|
|
337
|
+
| `search` | Semantic + keyword + graph hybrid search |
|
|
338
|
+
| `code` | AST operations: symbol search, pattern search/rewrite, document symbols |
|
|
339
|
+
| `find_symbol` | Find a symbol's definition |
|
|
340
|
+
| `find_callers` | Who calls this function? |
|
|
341
|
+
| `find_callees` | What does this function call? |
|
|
342
|
+
| `explain` | Full symbol explanation: definition + callers + callees + related code |
|
|
343
|
+
| `impact` | What breaks if I change this? (transitive caller analysis) |
|
|
344
|
+
| `analyze` | Code smells, complexity, quality score |
|
|
345
|
+
| `overview` | Project structure: languages, files, directories, symbols |
|
|
346
|
+
| `architecture` | Layers, entry points, hub symbols |
|
|
347
|
+
| `commit_search` | Semantic search over git commit history |
|
|
348
|
+
| `commit_history` | Browse recent commits |
|
|
349
|
+
| `repo_add` | Register another repo for unified search |
|
|
350
|
+
| `repo_remove` | Unregister a repo |
|
|
351
|
+
| `repo_status` | View all repos and watcher status |
|
|
352
|
+
| `remember` | Store a note or decision with tags and TTL |
|
|
353
|
+
| `recall` | Search memories (and compaction archive) by meaning |
|
|
354
|
+
| `forget` | Delete memories |
|
|
355
|
+
| `knowledge` | Index and search your own docs/notes/files |
|
|
356
|
+
| `compact` | Archive session content before compaction |
|
|
357
|
+
| `session_snapshot` | Compressed session state for context recovery |
|
|
358
|
+
| `introspect` | Look up Contextro's own tool docs and settings |
|
|
359
|
+
| `retrieve` | Fetch sandboxed large output by reference ID |
|
|
360
|
+
| `status` | Server status, index stats, cache hit rate |
|
|
361
|
+
| `health` | Readiness check |
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## How Search Works
|
|
366
|
+
|
|
367
|
+
When you call `search("how does auth work")`, Contextro:
|
|
368
|
+
|
|
369
|
+
1. Checks the query cache for a semantic or exact hit
|
|
370
|
+
2. Runs vector search (semantic), BM25 (keyword), and graph search (connectivity) in parallel
|
|
371
|
+
3. Fuses results with Reciprocal Rank Fusion
|
|
372
|
+
4. Optionally reranks with FlashRank
|
|
373
|
+
5. Filters low-relevance results (threshold: 40% of top score)
|
|
374
|
+
6. Applies diversity penalty (no 5 results from the same file)
|
|
375
|
+
7. Compresses code snippets with AST-aware compression
|
|
376
|
+
8. Returns confidence level (`high`/`medium`/`low`), token count, and `sandbox_ref` if needed
|
|
377
|
+
|
|
378
|
+
Every step is designed to balance relevance, speed, and token efficiency.
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Configuration
|
|
383
|
+
|
|
384
|
+
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.
|
|
385
|
+
|
|
386
|
+
### Common settings
|
|
387
|
+
|
|
388
|
+
| Variable | Default | What it does |
|
|
389
|
+
|---|---|---|
|
|
390
|
+
| `CTX_STORAGE_DIR` | `~/.contextro` | Where the index is stored |
|
|
391
|
+
| `CTX_EMBEDDING_MODEL` | `potion-code-16m` | Embedding model (see below) |
|
|
392
|
+
| `CTX_AUTO_WARM_START` | `false` | Restore index on restart without re-indexing |
|
|
393
|
+
| `CTX_RELEVANCE_THRESHOLD` | `0.40` | How strict search filtering is (0–1) |
|
|
394
|
+
| `CTX_SEARCH_MODE` | `hybrid` | `hybrid`, `vector`, or `bm25` |
|
|
395
|
+
| `CTX_MAX_MEMORY_MB` | `350` | RAM budget |
|
|
396
|
+
| `CTX_COMMIT_HISTORY_ENABLED` | `true` | Index git commits for `commit_search` |
|
|
397
|
+
| `CTX_LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
|
|
398
|
+
| `CTX_TRANSPORT` | `stdio` | `stdio` (local) or `http` (Docker/remote) |
|
|
399
|
+
|
|
400
|
+
### Search tuning
|
|
401
|
+
|
|
402
|
+
| Variable | Default | What it does |
|
|
403
|
+
|---|---|---|
|
|
404
|
+
| `CTX_SEARCH_CACHE_MAX_SIZE` | `128` | Max cached search responses |
|
|
405
|
+
| `CTX_SEARCH_CACHE_TTL_SECONDS` | `300` | Cache expiry (seconds) |
|
|
406
|
+
| `CTX_SEARCH_SANDBOX_THRESHOLD_TOKENS` | `1200` | Sandbox responses above this size |
|
|
407
|
+
| `CTX_SEARCH_SANDBOX_TTL_SECONDS` | `600` | Sandbox expiry (seconds) |
|
|
408
|
+
| `CTX_SEARCH_PREVIEW_RESULTS` | `4` | Preview results when sandboxing |
|
|
409
|
+
| `CTX_SEARCH_PREVIEW_CODE_CHARS` | `220` | Code preview length |
|
|
410
|
+
|
|
411
|
+
### Indexing tuning
|
|
412
|
+
|
|
413
|
+
| Variable | Default | What it does |
|
|
414
|
+
|---|---|---|
|
|
415
|
+
| `CTX_CHUNK_CONTEXT_MODE` | `rich` | Chunk header style: `minimal` or `rich` |
|
|
416
|
+
| `CTX_SMART_CHUNK_RELATIONSHIPS_ENABLED` | `true` | Index caller→callee relationship chunks |
|
|
417
|
+
| `CTX_SMART_CHUNK_FILE_CONTEXT_ENABLED` | `true` | Index file-overview chunks |
|
|
418
|
+
| `CTX_COMMIT_HISTORY_LIMIT` | `500` | Max commits to index |
|
|
419
|
+
| `CTX_REALTIME_INDEXING_ENABLED` | `true` | Auto-reindex on branch switch |
|
|
420
|
+
|
|
421
|
+
### Embedding models
|
|
422
|
+
|
|
423
|
+
| Model | Speed | Quality | Best for |
|
|
424
|
+
|---|---|---|---|
|
|
425
|
+
| `potion-code-16m` ⭐ | 55k/sec | 99% of SOTA | Daily coding — best balance |
|
|
426
|
+
| `potion-8m` | 80k/sec | Good | Maximum speed |
|
|
427
|
+
| `jina-code` | 15/sec | Best | Small projects, max precision |
|
|
428
|
+
| `nomic-embed` | 15/sec | Good | Docs and markdown |
|
|
429
|
+
| `bge-small-en` | 22/sec | OK | Legacy use |
|
|
430
|
+
|
|
431
|
+
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.
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Docker (Team / Server Use)
|
|
436
|
+
|
|
437
|
+
If you want to run Contextro on a server and share it across a team:
|
|
438
|
+
|
|
439
|
+
```yaml
|
|
440
|
+
# docker-compose.yml
|
|
441
|
+
services:
|
|
442
|
+
contextro:
|
|
443
|
+
container_name: contextro-mcp
|
|
444
|
+
image: ghcr.io/jassskalkat/contextro-mcp:latest
|
|
445
|
+
ports:
|
|
446
|
+
- "8000:8000"
|
|
447
|
+
volumes:
|
|
448
|
+
- contextro-data:/data
|
|
449
|
+
- ${CTX_CODEBASE_HOST_PATH}:/repos/platform:ro
|
|
450
|
+
environment:
|
|
451
|
+
CTX_STORAGE_DIR: /data/.contextro
|
|
452
|
+
CTX_CODEBASE_HOST_PATH: ${CTX_CODEBASE_HOST_PATH}
|
|
453
|
+
CTX_CODEBASE_MOUNT_PATH: /repos/platform
|
|
454
|
+
CTX_TRANSPORT: http
|
|
455
|
+
CTX_HTTP_HOST: 0.0.0.0
|
|
456
|
+
CTX_HTTP_PORT: "8000"
|
|
457
|
+
CTX_AUTO_WARM_START: "true"
|
|
458
|
+
|
|
459
|
+
volumes:
|
|
460
|
+
contextro-data:
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
export CTX_CODEBASE_HOST_PATH=/path/to/your/project
|
|
465
|
+
docker compose up -d
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
The image auto-remaps your host path inside the container. Pull it directly:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
docker pull ghcr.io/jassskalkat/contextro-mcp:latest
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Performance
|
|
477
|
+
|
|
478
|
+
| Metric | Value |
|
|
479
|
+
|---|---|
|
|
480
|
+
| Indexing speed | 3,349 files in 8.1s |
|
|
481
|
+
| Incremental reindex | 22ms (no changes) |
|
|
482
|
+
| Search latency | <2ms (warm index) |
|
|
483
|
+
| File discovery | 15ms for 3,349 files |
|
|
484
|
+
| Token reduction | 65–90% vs raw file reading |
|
|
485
|
+
| Memory usage | <350MB |
|
|
486
|
+
| Progressive disclosure savings | ~44% on large responses |
|
|
487
|
+
| AST snippet compression | ~73% on code previews |
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## License
|
|
492
|
+
|
|
493
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
contextro_mcp/__init__.py,sha256=wIjlN0mB-vn0A7DIy_eTseZ9gR47Idg7-5aZ0xZ61o8,121
|
|
2
|
+
contextro_mcp/accelerator.py,sha256=msB-wLCLvdifDQTXJ0wLiJiEN3cfs0nktT7oeMBuO3s,9434
|
|
3
|
+
contextro_mcp/config.py,sha256=MWoljVdmnfdCoqHW6BjDNQ2f0U2LJt4zowiakWIhCl8,10239
|
|
4
|
+
contextro_mcp/server.py,sha256=6HSNZBl6wlpG5CldshRmH5sIan_qEAIgrKcibci2byQ,126747
|
|
5
|
+
contextro_mcp/state.py,sha256=1I--sJK952Y_DBqcR8rhSRMJCoWsqyPC-JP4z-hD0Z0,9135
|
|
6
|
+
contextro_mcp/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
contextro_mcp/analysis/code_analyzer.py,sha256=ur5otCx3WliU6VSRZN4pDklqkrr_aHlCeexvl9NiIVU,8604
|
|
8
|
+
contextro_mcp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
contextro_mcp/core/exceptions.py,sha256=v9LZaM5ZWBFZOkozJPaAGQjeEMFcM7lIYKwQUzt7ai4,1511
|
|
10
|
+
contextro_mcp/core/graph_models.py,sha256=8jMv6Y_l7iUg2HhVgw5wvw9tVtWZ6XnVyANp3Pxe854,10188
|
|
11
|
+
contextro_mcp/core/interfaces.py,sha256=qEeybZ6Nj5hyswwKqiC3igm5xFnKO-zdXfvwkxPC8v0,1559
|
|
12
|
+
contextro_mcp/core/models.py,sha256=0phG3ugrba0nZrRnJwT0JLrLn09N-pTU2cajAvC8LTQ,9481
|
|
13
|
+
contextro_mcp/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
contextro_mcp/engines/bm25_engine.py,sha256=8aJwfRtOa427ZmvUeGSrGHNh6CQzCv9CQ21aEwsbRUA,5073
|
|
15
|
+
contextro_mcp/engines/fusion.py,sha256=CLXX0agg8o5ATufivQZ0zqB1CRNKhjJMYCFUgDl1Z9U,7474
|
|
16
|
+
contextro_mcp/engines/graph_engine.py,sha256=ndRWMuAbpUlBZ2m6db-n-UNbFaSxTgeTLq3AAl21cV0,11769
|
|
17
|
+
contextro_mcp/engines/live_grep.py,sha256=VK3-jzcQ_PMmXGqoM4A3hyUQjDNXWWBt7sBD60gTuiE,5908
|
|
18
|
+
contextro_mcp/engines/output_sandbox.py,sha256=5USgQ9dmK88TqiA49BYJhFMQpo-gv0D6HnpLzBpFFi0,4726
|
|
19
|
+
contextro_mcp/engines/query_cache.py,sha256=RuphuMATMfKUpXC5Ot-IWKbmgJubTHFgmb-kd7qG9p0,5491
|
|
20
|
+
contextro_mcp/engines/reranker.py,sha256=a3r3CZBvV-eVxHm3cSvzAY9Prr7pxnjFOCsajdCglu4,3786
|
|
21
|
+
contextro_mcp/engines/vector_engine.py,sha256=XxT9SdH48Ks1OhRhjk6rufss2oEyGw1ke0XnWWN7dUI,7258
|
|
22
|
+
contextro_mcp/execution/__init__.py,sha256=64KzXWwSLGlsHDRxGAss6-dF4CUTN_kA5XjIuZAhsno,350
|
|
23
|
+
contextro_mcp/execution/ast_compression.py,sha256=dPcRGo4-iwNgR1LTzbbXRJWLESHMyZ5jRJg9UMzdgqo,6735
|
|
24
|
+
contextro_mcp/execution/compaction.py,sha256=mJGyXQTsbSSDC3cDUI8KEpjgaMhomr9cmprURkltlDk,11134
|
|
25
|
+
contextro_mcp/execution/interfaces.py,sha256=J1AevOwiHD6yDgWRN_j2lt68cz-YTpfCS2XDBb8GSJ4,993
|
|
26
|
+
contextro_mcp/execution/response_policy.py,sha256=FeG6zhnXrCK69kXMxHKZG38Zo9LvTB7deGPLfuXGY04,10228
|
|
27
|
+
contextro_mcp/execution/runtime.py,sha256=BvrM0-AqodOqHNTie_F1IuAp4U6nd01iOwt2B26CpB0,2631
|
|
28
|
+
contextro_mcp/execution/search.py,sha256=QKxFLx8UGBIn-pCRHASwHyXHtTMY1uChiJHOftcxYe8,16076
|
|
29
|
+
contextro_mcp/formatting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
contextro_mcp/formatting/response_builder.py,sha256=sP2pypMylyvA79bJKYWdFeTVxCubAVYUPOyyWqzc1_4,4651
|
|
31
|
+
contextro_mcp/formatting/token_budget.py,sha256=zp9RRSavsx6ISyukziSX2XMIpJ0P7tlZftFVkTv56og,1883
|
|
32
|
+
contextro_mcp/formatting/toon_encoder.py,sha256=RDRTT_4DV4Ye_8oDksJ9-WUe-TzJcbKDG72DSTwWF38,2182
|
|
33
|
+
contextro_mcp/git/__init__.py,sha256=gIY7NAWHnLspH3fpQfZVk03pVkFXiKt0_k0VV5cttrI,91
|
|
34
|
+
contextro_mcp/git/branch_watcher.py,sha256=7xz_SeeL_9FfA2kUIgV0Rfvxv574ulA_nw9v7w1v80w,9038
|
|
35
|
+
contextro_mcp/git/commit_indexer.py,sha256=njT2Nx82oB_serWI9cJ2C5BZ_LudgxcldlpWgwra0mI,18250
|
|
36
|
+
contextro_mcp/git/cross_repo.py,sha256=Q3NpIa3LhTJI-MqnvOgPOGznJw0NCmo_-HIfKv7Lhpo,7024
|
|
37
|
+
contextro_mcp/indexing/__init__.py,sha256=O7Vant29HEue15wZh4LurF-KGMgqZ03QxHX77soeDqI,379
|
|
38
|
+
contextro_mcp/indexing/chunk_context.py,sha256=I4cds49OmDcN1w1o-nuH_a5KneLEuvTAuTR_R_hE8mM,3384
|
|
39
|
+
contextro_mcp/indexing/chunker.py,sha256=oUsra1oqDbhkksWaHUm_0gu-eQj29KKcy3zRzarH21U,4174
|
|
40
|
+
contextro_mcp/indexing/embedding_service.py,sha256=zQjV8X0rpprDw4nmxIrleT_X-WZn2afNi90XlSL2ZMU,15113
|
|
41
|
+
contextro_mcp/indexing/file_discovery.py,sha256=hL0m2bEf0ZaqPlR62DeYaGnYB0uYOOXCcrEx6MOJaYY,2796
|
|
42
|
+
contextro_mcp/indexing/parallel_indexer.py,sha256=F31k7HBk7yAYlS4t7rO-2LkEEYBTssfqvwZjJwKtrjM,4513
|
|
43
|
+
contextro_mcp/indexing/pipeline.py,sha256=Jq1HhYmk9SoMM2n9KVzx2OdrS9d8Qhr0G_Tjt0S7duU,33317
|
|
44
|
+
contextro_mcp/indexing/smart_chunker.py,sha256=LxczTX4alzs3b49i2lDebnVa56QujwVa6dH9VCdKlHk,7822
|
|
45
|
+
contextro_mcp/memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
contextro_mcp/memory/compaction_archive.py,sha256=XghvSwUJIUjB7MKhAPo9sWB6LCr0j0C-WUfUMbz7C-k,4289
|
|
47
|
+
contextro_mcp/memory/memory_store.py,sha256=Ujh0ErgkeurdvojuAmd3U7f6b7gYKu8WK4Z8NmAG4GQ,10660
|
|
48
|
+
contextro_mcp/memory/session_tracker.py,sha256=Ho1FTXeePAHPnS2nOQUAW3FUYUJizuAjPiJ1ZXx-jAs,4794
|
|
49
|
+
contextro_mcp/middleware/__init__.py,sha256=5of7wBhgBN78kPbRo4WW1QNoLlB0bxIBdTYRxtrnFgI,54
|
|
50
|
+
contextro_mcp/middleware/audit.py,sha256=GF2e-TDsr5mHme6JB1hOUoJSkb2gsT0EiOc8ZsqOuTc,2371
|
|
51
|
+
contextro_mcp/parsing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
|
+
contextro_mcp/parsing/astgrep_parser.py,sha256=RrDvBOEJuQ94r9ttjGB99yIs3kFxu39UiDqCrUMa0bc,15526
|
|
53
|
+
contextro_mcp/parsing/file_watcher.py,sha256=i9m11iM8ZUTdsQ0Pg6aD8lQ826jG_O2Nkbq0c1RV1cA,6137
|
|
54
|
+
contextro_mcp/parsing/language_registry.py,sha256=e5N57fscLj0MvvM3pDjgHvILiU8ZigvDnoPxWao5cyM,8284
|
|
55
|
+
contextro_mcp/parsing/treesitter_parser.py,sha256=QPlsUvqdmTd0TR-cjCJ6L_BHe-1O4Qks1oa3SbHkZOc,15912
|
|
56
|
+
contextro_mcp/persistence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
+
contextro_mcp/persistence/store.py,sha256=51LYrs4qT2yybcOE0LM8xgyaxR2_RRRcUHdNsyObBoQ,6812
|
|
58
|
+
contextro_mcp/research/__init__.py,sha256=32PNC87Dbst5wSjGXZMfS7ZJ-iJGLX1HnANNChV7Cks,255
|
|
59
|
+
contextro_mcp/research/catalog.py,sha256=kL3qy8OA2zc7qhOq7FiQ7mu9n2jZyXlwZfdQ-i-TkDY,9126
|
|
60
|
+
contextro_mcp/schemas/__init__.py,sha256=5WQ3W0XYO1DLyBRHmlJjhSd9pZgmO8-CAAOLaPp3484,1169
|
|
61
|
+
contextro_mcp/schemas/inputs.py,sha256=wFjaONnOn8Yi2QtcJuLvPXPYvkXM3zYJ1iiJZdByQXc,5745
|
|
62
|
+
contextro_mcp/schemas/responses.py,sha256=xuetWU8lcesQsy7F7iaCBxuUU__3i2ywcpbzDZr_fCY,5204
|
|
63
|
+
contextro_mcp/security/__init__.py,sha256=_qRfcUtlQ5hA2JnPzKkzHB9uxM40y5BKuADN2QFRyFk,65
|
|
64
|
+
contextro_mcp/security/permissions.py,sha256=LvO3PvZ-GRXDlbRzGy74Scnv6FCmV4siSyFXNTD_bp0,3278
|
|
65
|
+
contextro_mcp/security/rate_limiter.py,sha256=ohtvCZ0Tvr3wNgqw6YCi2EYZM3LhvGbx243MEET8Kuc,2760
|
|
66
|
+
contextro-0.0.1.dist-info/METADATA,sha256=lY2sVUFsjlY3u3PVSYo3tl_PQa0xXVh-NCpVDFXGQgc,15834
|
|
67
|
+
contextro-0.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
68
|
+
contextro-0.0.1.dist-info/entry_points.txt,sha256=OrEfxDuAp3Dd3ah7sbp0r07zOqhwznJ8tMm3Tudw7KU,56
|
|
69
|
+
contextro-0.0.1.dist-info/licenses/LICENSE,sha256=BnA6a8URgi--U_dpxODGYkTMnJaoSM9QvoPVRAWqWrc,1074
|
|
70
|
+
contextro-0.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shreyas Jagannath
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|