Install
$ agentstack add mcp-viperjuice-code-index-mcp Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Pipes remote content directly into a shell (remote code execution).
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Code-Index-MCP (Local-first Code Indexer)
Modular, extensible local-first code indexer designed to enhance Claude Code and other LLMs with deep code understanding capabilities. Built on the Model Context Protocol (MCP) for seamless integration with AI assistants.
> Stable-surface prep status: This guide targets 1.2.0 and reflects the > repo-owned stable install surface prepared by GAREL. MCP STDIO remains the > primary LLM surface, FastAPI remains a secondary admin surface, and final > release publication plus GA release evidence remain downstream-only in > GADISP.
Project Status
Version: 1.2.0 (stable surface prepared; dispatch pending) Python distribution: index-it-mcp Container image: ghcr.io/viperjuice/code-index-mcp Primary surface: MCP tools (search_code, symbol_lookup) via the STDIO runner when repository readiness is ready Secondary surface: FastAPI admin REST gateway for diagnostics and scripting — see "Admin REST Interface (secondary)" below Core features: local indexing, symbol/text search, registry-based language coverage; see [docs/SUPPORTMATRIX.md](docs/SUPPORTMATRIX.md) Optional features: semantic search (requires Voyage AI or a local vLLM endpoint), GitHub Artifacts index sync Performance: sub-100ms symbol lookup and sub-500ms search on indexed repos (benchmarked on this codebase; results vary by repo size and language mix) GA decision: see [docs/validation/ga-final-decision.md](docs/validation/ga-final-decision.md); the current decision is ship GA, but stable release mutation and release evidence remain downstream-only in GADISP. GA readiness contract: see [docs/validation/ga-readiness-checklist.md](docs/validation/ga-readiness-checklist.md) for the frozen release boundary, support-tier labels, evidence ownership, and rollback expectations that apply before dispatch. Repository model: one server can serve many unrelated repositories, with one registered worktree per git common directory. Only the tracked/default branch is indexed automatically. Indexed MCP results are authoritative only when readiness is ready; unavailable indexes return index_unavailable with safe_fallback: "native_search".
> New to Code-Index-MCP? Check out our [Getting Started Guide](docs/GETTING_STARTED.md) for a quick walkthrough.
🎯 Key Features
- 🚀 Local-First Architecture: All indexing happens locally for speed and privacy
- 📂 Local Index Storage: All indexes stored at
.indexes/(relative to MCP server) - 🔌 Plugin-Based Design: Easily extensible with language-specific plugins
- 🔍 Language support: Tiered language/runtime support is documented in [docs/SUPPORTMATRIX.md](docs/SUPPORTMATRIX.md)
- ⚡ Real-Time Updates: File system monitoring for instant index updates
- 🧠 Semantic Search: AI-powered code search with Voyage AI embeddings
- 📊 Rich Code Intelligence: Symbol resolution, type inference, dependency tracking
- 🚀 Enhanced Performance: Sub-100ms queries with timeout protection and BM25 bypass
- 🔄 Git Synchronization: Automatic index updates tracking repository changes
- 📦 Portable Index Management: Zero-cost index sharing via GitHub Artifacts
- 🔄 Automatic Index Sync: Pull indexes on clone, push on changes
- 🎯 Smart Result Reranking: Multi-strategy reranking for improved relevance
- 🎯 Query-Intent Routing: Symbol-pattern queries (
class Foo,def bar, CamelCase) bypass BM25 and hit the symbols table directly for sub-5ms lookups - 🔒 Security-Aware Export: Automatic filtering of sensitive files from shared indexes
- 🔍 Hybrid Search: BM25 + semantic search with configurable fusion
- 🔐 Index Everything Locally: Search .env files and secrets on your machine
- 🚫 Smart Filtering on Share: .gitignore and .mcp-index-ignore patterns applied only during export
- 🌐 Multi-Language Indexing: Index entire repositories with mixed languages
🏗️ Architecture
The Code-Index-MCP follows a modular, plugin-based architecture designed for extensibility and performance:
System Layers
- 🌐 System Context (Level 1)
- Developer interacts with Claude Code or other LLMs
- MCP protocol provides standardized tool interface
- Local-first processing with optional cloud features
- Performance SLAs:
(registered name or path) tosearchcode/symbollookup`:
search_code(query="def parse", repository="my-repo")
symbol_lookup(symbol="Parser", repository="my-repo")
Index tracking: each repo's tracked/default branch is followed by MultiRepositoryWatcher (RefPoller every 30 s). Same-repo multiple worktrees and non-default branch queries are unsupported in v3 routing: they return index_unavailable with safe_fallback: "native_search" and readiness remediation instead of reusing another checkout's index. Check get_status or mcp-index repository list -v and trust indexed MCP results only when readiness is ready.
Path sandbox: tools search_code, symbol_lookup, summarize_sample, and reindex reject paths outside MCP_ALLOWED_ROOTS with error code path_outside_allowed_roots. Registered repo names bypass the check.
Options:
- Set
MCP_AUTO_INDEX=falsein the server environment to skip background auto-indexing and call thereindexMCP tool manually (recommended for very large repos). - Add
{"enabled": false}to.mcp-index.jsonin the target repo to disable indexing for that repo entirely. - After a full reindex or code changes, call the
reindexMCP tool to rebuild the index on demand.
Semantic profiles: BM25 search requires no extra config. For semantic (vector) search, the server automatically loads code-index-mcp.profiles.yaml from its own installation directory — no need to copy it to each repo. To override with a custom profile file, set MCP_PROFILES_PATH=/abs/path/to/your-profiles.yaml in the server environment. To override individual endpoint URLs without editing the YAML, use the env vars referenced in the file (e.g. VLLM_EMBEDDING_BASE_URL, VLLM_SUMMARIZATION_BASE_URL).
⚡ Enable Semantic Search
BM25 keyword search works with zero configuration. To add vector (semantic) search, choose one path:
Option A — Voyage AI (recommended):
export VOYAGE_API_KEY=your-key # free tier available at voyageai.com
The commercial_high profile activates automatically. Restart the MCP server — the startup log will confirm semantic search is active.
Option B — Local OSS (Qwen3-Embedding-8B via vLLM, no API key needed):
export VLLM_EMBEDDING_BASE_URL=http://localhost:8000/v1
# Start vLLM (requires ~20GB VRAM or shared CPU with --dtype float32):
docker run -p 8000:8000 vllm/vllm-openai --model Qwen/Qwen3-Embedding-8B
Both profiles and their collection names are defined in code-index-mcp.profiles.yaml and can be customized.
Costs & Optional Features
The documented container package is ghcr.io/viperjuice/code-index-mcp. BM25 code search works without provider credentials. Semantic search, reranking, artifact sync, and monitoring depend on extras, environment variables, and service configuration. See [docs/SUPPORTMATRIX.md](docs/SUPPORTMATRIX.md) for language/runtime support details.
🚀 Quickstart (Python)
Prerequisites
- Python 3.12+
- Git
Installation
Option 1: Install via pip (Recommended)
# Install the prepared stable package surface
pip install index-it-mcp==1.2.0
# Or install with dev tools for testing
pip install "index-it-mcp[dev]==1.2.0"
Option 2: Install from Source
# Clone the repository
git clone https://github.com/ViperJuice/Code-Index-MCP.git
cd Code-Index-MCP
# Install locked project dependencies
uv sync --locked
Quick Start After Installation
# Authenticate GitHub artifact access once
gh auth login
# Check repo/artifact readiness before starting work
mcp-index preflight
# Pull the latest published index baseline for this repo
mcp-index artifact pull --latest
# Reconcile only your local drift after restore
mcp-index artifact sync
# The restored files live locally for MCP runtime use:
# - code_index.db
# - .index_metadata.json
# - vector_index.qdrant/
# Check index status
mcp-index index status
# Start the MCP STDIO runner (primary surface used by LLMs via .mcp.json)
python -m mcp_server.cli.stdio_runner
# Or start the FastAPI admin REST gateway (secondary, for diagnostics)
mcp-index serve
mcp-index serve --port 9123 # alternate port
From an LLM (Claude Code, Cursor, …) register the STDIO runner in .mcp.json and invoke the indexer as MCP tool calls. The two primary tools are search_code (pattern / keyword / semantic search, :8001/v1`
- SSH Tunnel: Run
ssh -L 8001:localhost:8001 user@remote-gpu-machine, and the default127.0.0.1:8001configuration will tunnel directly to your inference server.
The generated index files are not meant to live in git history. The repo tracks the code, workflow, and configuration needed to build/publish them; GitHub artifacts distribute the actual runtime baseline that MCP restores locally.
Local Workspace Management
# Inspect all registered repositories and their readiness
mcp-index repository list -v
# Check all registered repos and their local artifact/runtime readiness
mcp-index artifact workspace-status
# Refresh readiness after restoring or rebuilding local indexes
mcp-index artifact reconcile-workspace
# Prepare per-repo local artifact payloads without requiring remote publication
mcp-index artifact publish-workspace
MRREADY freezes the rollout-facing interpretation of those commands:
mcp-index repository list -v,mcp-index repository status, and
mcp-index artifact workspace-status now surface one rollout status per repository: ready, local_only, publish_failed, wrong_branch, stale_commit, missing_index, or partial_index_failure.
- Query tools remain a separate fail-closed surface. If readiness is not
ready, MCP search returns index_unavailable with safe_fallback: "native_search" instead of treating a status row as a query success.
- The current multi-repo verdict remains
controlled rollout onlywhile the
multi-repo and STDIO surfaces are still beta.
🔐 Privacy & GitHub Artifact Sync
Control how your code index is shared:
// .mcp-index.json
{
"github_artifacts": {
"enabled": false, // Disable sync entirely
"auto_upload": false, // Manual upload only
"auto_download": true, // Still get team indexes
"exclude_patterns": [ // Additional exclusions
"internal/*",
"proprietary/*"
]
}
}
Privacy Features:
- Indexes filtered by .gitignore automatically
- Additional patterns via .mcp-index-ignore
- Audit logs show what was excluded
- Sync disabled by default in Docker minimal version
🆕 Advanced Features
Search Result Reranking
Three rerankers are available, configured via the RERANKER_TYPE environment variable:
| Value | Reranker | Notes | |---|---|---| | flashrank | FlashRank | OSS, local, fast (~1–5 ms overhead) | | cross-encoder | Cross-Encoder | OSS, local, highest quality | | voyage | Voyage Reranker | Cloud API, requires VOYAGE_API_KEY | | none | Disabled | Default |
export RERANKER_TYPE=flashrank # or cross-encoder, voyage, none
Reranking applies only to the semantic retrieval path. BM25/FTS results are not reranked. Implementation: mcp_server/dispatcher/reranker.py.
LLM Chunk Summarization
Semantic chunks can be augmented with LLM-generated summaries before embedding, improving retrieval of intent-based queries. Configured per-profile in code-index-mcp.profiles.yaml:
summarization:
enabled: true
mode: lazy # lazy (on first query) | comprehensive (at index time)
provider: openai_compatible
model_name: gpt-4o-mini
base_url: "https://api.openai.com/v1"
api_key_env: OPENAI_API_KEY
prompt_template: "Describe this code chunk's inputs, outputs, and purpose in 2 concise sentences."
> ⚠️ Security: Do not summarize untrusted code with cloud LLMs. Hidden instructions in > comments can be executed by the summarizer. See the [Security Notes](#-security-notes) section.
Implementation: mcp_server/indexing/summarization.py
Security-Aware Index Sharing
Prevent accidental sharing of sensitive files:
# Analyze current index for security issues
python scripts/utilities/analyze_gitignore_security.py
# Create secure index export (filters gitignored files)
python scripts/utilities/secure_index_export.py
# The secure export will:
# - Exclude all gitignored files
# - Remove sensitive patterns (*.env, *.key, etc.)
# - Create audit logs of excluded files
BM25 Hybrid Search
Combines traditional full-text search with semantic search:
# The system automatically uses hybrid search when available
# Configure weights in settings:
HYBRID_SEARCH_BM25_WEIGHT=0.3
HYBRID_SEARCH_SEMANTIC_WEIGHT=0.5
HYBRID_SEARCH_FUZZY_WEIGHT=0.2
🔧 Dispatcher Configuration
Enhanced Dispatcher (Default)
The enhanced dispatcher includes timeout protection and automatic fallback:
from mcp_server.dispatcher.dispatcher_enhanced import EnhancedDispatcher
from mcp_server.storage.sqlite_store import SQLiteStore
store = SQLiteStore(".indexes/YOUR_REPO_ID/current.db")
dispatcher = EnhancedDispatcher(
sqlite_store=store,
semantic_search_enabled=True, # Enable if Qdrant available
lazy_load=True, # Load plugins on-demand
use_plugin_factory=True # Use dynamic plugin loading
)
# Search with automatic optimization
results = list(dispatcher.search("your query", limit=10))
Simple Dispatcher (Lightweight Alternative)
For maximum performance with BM25-only search:
from mcp_server.dispatcher.simple_dispatcher import create_simple_dispatcher
# Ultra-fast BM25 search without plugin overhead
dispatcher = create_simple_dispatcher(".indexes/YOUR_REPO_ID/current.db")
results = list(dispatcher.search("your query", limit=10))
Configuration Options
Configure dispatcher behavior via environment variables:
# Dispatcher settings
MCP_DISPATCHER_TIMEOUT=5 # Plugin loading timeout (seconds)
MCP_USE_SIMPLE_DISPATCHER=false # Use simple dispatcher
MCP_PLUGIN_LAZY_LOAD=true # Load plugins on-demand
# Performance tuning
MCP_BM25_BYPASS_ENABLED=true # Enable direct BM25 bypass
MCP_MAX_PLUGIN_MEMORY=1024 # Max memory for plugins (MB)
# Auto-indexing (cross-repo use)
MCP_AUTO_INDEX=true # Set false to skip background auto-index on first run
MCP_AUTO_INDEX_MAX_FILES=100000 # Skip auto-index if repo exceeds this file count
MCP_PROFILES_PATH= # Absolute path to a custom profiles YAML (overrides built-in)
# Endpoint overrides (no need to edit profiles.yaml)
VLLM_EMBEDDING_BASE_URL= # Override vLLM embedding endpoint (default: http://ai:8001/v1)
VLLM_SUMMARIZATION_BASE_URL= # Override summarization endpoint (default: http://win:8002/v1)
🗂️ Index Management
Centralized Index Storage
All indexes are now stored centrally at .indexes/ (relative to the MCP project) for better organization and to prevent accidental commits:
.indexes/
├── {repo_hash}/ # Unique hash for each repository
│ ├── main_abc123.db # Index for main branch at commit abc123
│ ├── main_abc123.metadata.json
│ └── current.db -> main_abc123.db # Symlink to active index
├── qdrant/ # Semantic search embeddings
│ └── main.qdrant/ # Centralized Qdrant database
Benefits:
- Indexes never accidentally committed to git
- Reusable across multiple clones of same repository
- Clear separation between code and indexes
- Automatic discovery based on git remote
Migration: For existing repositories with local
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ViperJuice
- Source: ViperJuice/Code-Index-MCP
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.